Add a Custom variant to Any*Event enums
This commit is contained in:
parent
184aafa5f6
commit
69d5da4018
@ -12,6 +12,7 @@ pub fn expand_event_enum(input: EventEnumInput) -> syn::Result<TokenStream> {
|
||||
let attrs = &input.attrs;
|
||||
let ident = &input.name;
|
||||
let event_type_str = &input.events;
|
||||
let event_struct = Ident::new(&ident.to_string().trim_start_matches("Any"), ident.span());
|
||||
|
||||
let variants = input.events.iter().map(to_camel_case).collect::<syn::Result<Vec<_>>>()?;
|
||||
let content = input.events.iter().map(to_event_path).collect::<Vec<_>>();
|
||||
@ -26,6 +27,8 @@ pub fn expand_event_enum(input: EventEnumInput) -> syn::Result<TokenStream> {
|
||||
#[doc = #event_type_str]
|
||||
#variants(#content),
|
||||
)*
|
||||
/// An event not defined by the Matrix specification
|
||||
Custom(::ruma_events::#event_struct<::ruma_events::custom::CustomEventContent>),
|
||||
}
|
||||
};
|
||||
|
||||
@ -46,7 +49,13 @@ pub fn expand_event_enum(input: EventEnumInput) -> syn::Result<TokenStream> {
|
||||
Ok(#ident::#variants(event))
|
||||
},
|
||||
)*
|
||||
_ => Err(D::Error::custom(format!("event type `{}` is not a valid event", ev_type)))
|
||||
event => {
|
||||
let event =
|
||||
::serde_json::from_str::<::ruma_events::#event_struct<::ruma_events::custom::CustomEventContent>>(json.get())
|
||||
.map_err(D::Error::custom)?;
|
||||
|
||||
Ok(Self::Custom(event))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,7 +91,7 @@ pub fn expand_content_enum(input: EventEnumInput) -> syn::Result<TokenStream> {
|
||||
#[doc = #event_type_str]
|
||||
#variants(#content),
|
||||
)*
|
||||
/// Any custom event.
|
||||
/// Content of an event not defined by the Matrix specification.
|
||||
Custom(::ruma_events::custom::CustomEventContent),
|
||||
}
|
||||
};
|
||||
|
@ -27,7 +27,20 @@ mod event_enum;
|
||||
///
|
||||
/// This macro also implements the necessary traits for the type to serialize and deserialize
|
||||
/// itself.
|
||||
// TODO more docs/example
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```ignore
|
||||
/// use ruma_events_macros::event_enum;
|
||||
///
|
||||
/// event_enum! {
|
||||
/// name: AnyBarEvent, // `BarEvent` has to be a valid type at `::ruma_events::BarEvent`
|
||||
/// events: [
|
||||
/// "m.any.event",
|
||||
/// "m.other.event",
|
||||
/// ]
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro]
|
||||
pub fn event_enum(input: TokenStream) -> TokenStream {
|
||||
let event_enum_input = syn::parse_macro_input!(input as EventEnumInput);
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! Types for custom events outside of the Matrix specification.
|
||||
|
||||
use std::time::SystemTime;
|
||||
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
use serde::Serialize;
|
||||
use serde_json::{value::RawValue as RawJsonValue, Value as JsonValue};
|
||||
|
||||
use crate::{EventContent, UnsignedData};
|
||||
use crate::{
|
||||
BasicEventContent, EphemeralRoomEventContent, EventContent, MessageEventContent,
|
||||
RoomEventContent, StateEventContent,
|
||||
};
|
||||
|
||||
/// A custom event's type and `content` JSON object.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
@ -31,56 +31,14 @@ impl EventContent for CustomEventContent {
|
||||
}
|
||||
}
|
||||
|
||||
/// A custom event not covered by the Matrix specification.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomBasicEvent {
|
||||
/// The event's content.
|
||||
pub content: CustomEventContent,
|
||||
}
|
||||
// A custom event must satisfy all of the event content marker traits since
|
||||
// they can be used for any event kind.
|
||||
impl RoomEventContent for CustomEventContent {}
|
||||
|
||||
/// A custom message event not covered by the Matrix specification.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomMessageEvent {
|
||||
/// The event's content.
|
||||
pub content: CustomEventContent,
|
||||
impl BasicEventContent for CustomEventContent {}
|
||||
|
||||
/// Time on originating homeserver when this event was sent.
|
||||
pub origin_server_ts: SystemTime,
|
||||
impl EphemeralRoomEventContent for CustomEventContent {}
|
||||
|
||||
/// The unique identifier for the room associated with this event.
|
||||
pub room_id: Option<RoomId>,
|
||||
impl MessageEventContent for CustomEventContent {}
|
||||
|
||||
/// The unique identifier for the user who sent this event.
|
||||
pub sender: UserId,
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
pub unsigned: UnsignedData,
|
||||
}
|
||||
|
||||
/// A custom state event not covered by the Matrix specification.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomStateEvent {
|
||||
/// The event's content.
|
||||
pub content: CustomEventContent,
|
||||
|
||||
/// The unique identifier for the event.
|
||||
pub event_id: EventId,
|
||||
|
||||
/// Time on originating homeserver when this event was sent.
|
||||
pub origin_server_ts: SystemTime,
|
||||
|
||||
/// The previous content for this state key, if any.
|
||||
pub prev_content: Option<CustomEventContent>,
|
||||
|
||||
/// The unique identifier for the room associated with this event.
|
||||
pub room_id: Option<RoomId>,
|
||||
|
||||
/// The unique identifier for the user who sent this event.
|
||||
pub sender: UserId,
|
||||
|
||||
/// A key that determines which piece of room state the event represents.
|
||||
pub state_key: String,
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
pub unsigned: UnsignedData,
|
||||
}
|
||||
impl StateEventContent for CustomEventContent {}
|
||||
|
@ -160,7 +160,6 @@ pub mod typing;
|
||||
|
||||
pub use self::{
|
||||
algorithm::Algorithm,
|
||||
custom::{CustomBasicEvent, CustomMessageEvent, CustomStateEvent},
|
||||
enums::{
|
||||
AnyBasicEvent, AnyBasicEventContent, AnyEphemeralRoomEvent, AnyEphemeralRoomEventContent,
|
||||
AnyEvent, AnyMessageEvent, AnyMessageEventContent, AnyMessageEventStub, AnyRoomEvent,
|
||||
|
@ -5,7 +5,7 @@ use std::{
|
||||
|
||||
use matches::assert_matches;
|
||||
use ruma_events::{
|
||||
custom::CustomEventContent, AnyMessageEventContent, AnyStateEventContent, EventJson,
|
||||
custom::CustomEventContent, AnyMessageEvent, AnyStateEvent, AnyStateEventContent, EventJson,
|
||||
MessageEvent, StateEvent, StateEventStub, UnsignedData,
|
||||
};
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
@ -36,8 +36,8 @@ fn custom_state_event() -> JsonValue {
|
||||
|
||||
#[test]
|
||||
fn serialize_custom_message_event() {
|
||||
let aliases_event = MessageEvent {
|
||||
content: AnyMessageEventContent::Custom(CustomEventContent {
|
||||
let aliases_event = AnyMessageEvent::Custom(MessageEvent {
|
||||
content: CustomEventContent {
|
||||
json: json!({
|
||||
"body": " * edited message",
|
||||
"m.new_content": {
|
||||
@ -51,13 +51,13 @@ fn serialize_custom_message_event() {
|
||||
"msgtype": "m.text"
|
||||
}),
|
||||
event_type: "m.room.message".to_string(),
|
||||
}),
|
||||
},
|
||||
event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(),
|
||||
origin_server_ts: UNIX_EPOCH + Duration::from_millis(10),
|
||||
room_id: RoomId::try_from("!room:room.com").unwrap(),
|
||||
sender: UserId::try_from("@carl:example.com").unwrap(),
|
||||
unsigned: UnsignedData::default(),
|
||||
};
|
||||
});
|
||||
|
||||
let actual = to_json_value(&aliases_event).unwrap();
|
||||
let expected = json!({
|
||||
@ -85,13 +85,13 @@ fn serialize_custom_message_event() {
|
||||
|
||||
#[test]
|
||||
fn serialize_custom_state_event() {
|
||||
let aliases_event = StateEvent {
|
||||
content: AnyStateEventContent::Custom(CustomEventContent {
|
||||
let aliases_event = AnyStateEvent::Custom(StateEvent {
|
||||
content: CustomEventContent {
|
||||
json: json!({
|
||||
"custom": 10
|
||||
}),
|
||||
event_type: "m.made.up".to_string(),
|
||||
}),
|
||||
},
|
||||
event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(),
|
||||
origin_server_ts: UNIX_EPOCH + Duration::from_millis(10),
|
||||
prev_content: None,
|
||||
@ -99,7 +99,7 @@ fn serialize_custom_state_event() {
|
||||
sender: UserId::try_from("@carl:example.com").unwrap(),
|
||||
state_key: "".to_string(),
|
||||
unsigned: UnsignedData::default(),
|
||||
};
|
||||
});
|
||||
|
||||
let actual = to_json_value(&aliases_event).unwrap();
|
||||
let expected = json!({
|
||||
@ -130,14 +130,14 @@ fn deserialize_custom_state_event() {
|
||||
});
|
||||
|
||||
assert_matches!(
|
||||
from_json_value::<EventJson<StateEvent<AnyStateEventContent>>>(json_data)
|
||||
from_json_value::<EventJson<AnyStateEvent>>(json_data)
|
||||
.unwrap()
|
||||
.deserialize()
|
||||
.unwrap(),
|
||||
StateEvent {
|
||||
content: AnyStateEventContent::Custom(CustomEventContent {
|
||||
AnyStateEvent::Custom(StateEvent {
|
||||
content: CustomEventContent {
|
||||
json, event_type,
|
||||
}),
|
||||
},
|
||||
event_id,
|
||||
origin_server_ts,
|
||||
sender,
|
||||
@ -145,7 +145,7 @@ fn deserialize_custom_state_event() {
|
||||
prev_content: None,
|
||||
state_key,
|
||||
unsigned,
|
||||
} if json == expected_content && event_type == "m.reaction"
|
||||
}) if json == expected_content && event_type == "m.reaction"
|
||||
&& event_id == EventId::try_from("$h29iv0s8:example.com").unwrap()
|
||||
&& origin_server_ts == UNIX_EPOCH + Duration::from_millis(10)
|
||||
&& sender == UserId::try_from("@carl:example.com").unwrap()
|
||||
|
@ -1,14 +1,14 @@
|
||||
use ruma_events_macros::event_enum;
|
||||
|
||||
event_enum! {
|
||||
name: InvalidEvent,
|
||||
name: AnyStateEvent,
|
||||
events: [
|
||||
"m.not.a.path",
|
||||
]
|
||||
}
|
||||
|
||||
event_enum! {
|
||||
name: InvalidEvent,
|
||||
name: AnyStateEvent,
|
||||
events: [
|
||||
"not.a.path",
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user