Add a Custom variant to Any*Event enums

This commit is contained in:
Ragotzy.devin 2020-06-19 12:32:42 -04:00 committed by GitHub
parent 184aafa5f6
commit 69d5da4018
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 73 deletions

View File

@ -12,6 +12,7 @@ pub fn expand_event_enum(input: EventEnumInput) -> syn::Result<TokenStream> {
let attrs = &input.attrs; let attrs = &input.attrs;
let ident = &input.name; let ident = &input.name;
let event_type_str = &input.events; 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 variants = input.events.iter().map(to_camel_case).collect::<syn::Result<Vec<_>>>()?;
let content = input.events.iter().map(to_event_path).collect::<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] #[doc = #event_type_str]
#variants(#content), #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)) 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] #[doc = #event_type_str]
#variants(#content), #variants(#content),
)* )*
/// Any custom event. /// Content of an event not defined by the Matrix specification.
Custom(::ruma_events::custom::CustomEventContent), Custom(::ruma_events::custom::CustomEventContent),
} }
}; };

View File

@ -27,7 +27,20 @@ mod event_enum;
/// ///
/// This macro also implements the necessary traits for the type to serialize and deserialize /// This macro also implements the necessary traits for the type to serialize and deserialize
/// itself. /// 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] #[proc_macro]
pub fn event_enum(input: TokenStream) -> TokenStream { pub fn event_enum(input: TokenStream) -> TokenStream {
let event_enum_input = syn::parse_macro_input!(input as EventEnumInput); let event_enum_input = syn::parse_macro_input!(input as EventEnumInput);

View File

@ -1,12 +1,12 @@
//! Types for custom events outside of the Matrix specification. //! Types for custom events outside of the Matrix specification.
use std::time::SystemTime;
use ruma_identifiers::{EventId, RoomId, UserId};
use serde::Serialize; use serde::Serialize;
use serde_json::{value::RawValue as RawJsonValue, Value as JsonValue}; 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. /// A custom event's type and `content` JSON object.
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
@ -31,56 +31,14 @@ impl EventContent for CustomEventContent {
} }
} }
/// A custom event not covered by the Matrix specification. // A custom event must satisfy all of the event content marker traits since
#[derive(Clone, Debug)] // they can be used for any event kind.
pub struct CustomBasicEvent { impl RoomEventContent for CustomEventContent {}
/// The event's content.
pub content: CustomEventContent,
}
/// A custom message event not covered by the Matrix specification. impl BasicEventContent for CustomEventContent {}
#[derive(Clone, Debug)]
pub struct CustomMessageEvent {
/// The event's content.
pub content: CustomEventContent,
/// Time on originating homeserver when this event was sent. impl EphemeralRoomEventContent for CustomEventContent {}
pub origin_server_ts: SystemTime,
/// The unique identifier for the room associated with this event. impl MessageEventContent for CustomEventContent {}
pub room_id: Option<RoomId>,
/// The unique identifier for the user who sent this event. impl StateEventContent for CustomEventContent {}
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,
}

View File

@ -160,7 +160,6 @@ pub mod typing;
pub use self::{ pub use self::{
algorithm::Algorithm, algorithm::Algorithm,
custom::{CustomBasicEvent, CustomMessageEvent, CustomStateEvent},
enums::{ enums::{
AnyBasicEvent, AnyBasicEventContent, AnyEphemeralRoomEvent, AnyEphemeralRoomEventContent, AnyBasicEvent, AnyBasicEventContent, AnyEphemeralRoomEvent, AnyEphemeralRoomEventContent,
AnyEvent, AnyMessageEvent, AnyMessageEventContent, AnyMessageEventStub, AnyRoomEvent, AnyEvent, AnyMessageEvent, AnyMessageEventContent, AnyMessageEventStub, AnyRoomEvent,

View File

@ -5,7 +5,7 @@ use std::{
use matches::assert_matches; use matches::assert_matches;
use ruma_events::{ use ruma_events::{
custom::CustomEventContent, AnyMessageEventContent, AnyStateEventContent, EventJson, custom::CustomEventContent, AnyMessageEvent, AnyStateEvent, AnyStateEventContent, EventJson,
MessageEvent, StateEvent, StateEventStub, UnsignedData, MessageEvent, StateEvent, StateEventStub, UnsignedData,
}; };
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
@ -36,8 +36,8 @@ fn custom_state_event() -> JsonValue {
#[test] #[test]
fn serialize_custom_message_event() { fn serialize_custom_message_event() {
let aliases_event = MessageEvent { let aliases_event = AnyMessageEvent::Custom(MessageEvent {
content: AnyMessageEventContent::Custom(CustomEventContent { content: CustomEventContent {
json: json!({ json: json!({
"body": " * edited message", "body": " * edited message",
"m.new_content": { "m.new_content": {
@ -51,13 +51,13 @@ fn serialize_custom_message_event() {
"msgtype": "m.text" "msgtype": "m.text"
}), }),
event_type: "m.room.message".to_string(), event_type: "m.room.message".to_string(),
}), },
event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(), event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(),
origin_server_ts: UNIX_EPOCH + Duration::from_millis(10), origin_server_ts: UNIX_EPOCH + Duration::from_millis(10),
room_id: RoomId::try_from("!room:room.com").unwrap(), room_id: RoomId::try_from("!room:room.com").unwrap(),
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
unsigned: UnsignedData::default(), unsigned: UnsignedData::default(),
}; });
let actual = to_json_value(&aliases_event).unwrap(); let actual = to_json_value(&aliases_event).unwrap();
let expected = json!({ let expected = json!({
@ -85,13 +85,13 @@ fn serialize_custom_message_event() {
#[test] #[test]
fn serialize_custom_state_event() { fn serialize_custom_state_event() {
let aliases_event = StateEvent { let aliases_event = AnyStateEvent::Custom(StateEvent {
content: AnyStateEventContent::Custom(CustomEventContent { content: CustomEventContent {
json: json!({ json: json!({
"custom": 10 "custom": 10
}), }),
event_type: "m.made.up".to_string(), event_type: "m.made.up".to_string(),
}), },
event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(), event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(),
origin_server_ts: UNIX_EPOCH + Duration::from_millis(10), origin_server_ts: UNIX_EPOCH + Duration::from_millis(10),
prev_content: None, prev_content: None,
@ -99,7 +99,7 @@ fn serialize_custom_state_event() {
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "".to_string(), state_key: "".to_string(),
unsigned: UnsignedData::default(), unsigned: UnsignedData::default(),
}; });
let actual = to_json_value(&aliases_event).unwrap(); let actual = to_json_value(&aliases_event).unwrap();
let expected = json!({ let expected = json!({
@ -130,14 +130,14 @@ fn deserialize_custom_state_event() {
}); });
assert_matches!( assert_matches!(
from_json_value::<EventJson<StateEvent<AnyStateEventContent>>>(json_data) from_json_value::<EventJson<AnyStateEvent>>(json_data)
.unwrap() .unwrap()
.deserialize() .deserialize()
.unwrap(), .unwrap(),
StateEvent { AnyStateEvent::Custom(StateEvent {
content: AnyStateEventContent::Custom(CustomEventContent { content: CustomEventContent {
json, event_type, json, event_type,
}), },
event_id, event_id,
origin_server_ts, origin_server_ts,
sender, sender,
@ -145,7 +145,7 @@ fn deserialize_custom_state_event() {
prev_content: None, prev_content: None,
state_key, state_key,
unsigned, 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() && event_id == EventId::try_from("$h29iv0s8:example.com").unwrap()
&& origin_server_ts == UNIX_EPOCH + Duration::from_millis(10) && origin_server_ts == UNIX_EPOCH + Duration::from_millis(10)
&& sender == UserId::try_from("@carl:example.com").unwrap() && sender == UserId::try_from("@carl:example.com").unwrap()

View File

@ -1,14 +1,14 @@
use ruma_events_macros::event_enum; use ruma_events_macros::event_enum;
event_enum! { event_enum! {
name: InvalidEvent, name: AnyStateEvent,
events: [ events: [
"m.not.a.path", "m.not.a.path",
] ]
} }
event_enum! { event_enum! {
name: InvalidEvent, name: AnyStateEvent,
events: [ events: [
"not.a.path", "not.a.path",
] ]