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 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),
}
};

View File

@ -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);

View File

@ -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 {}

View File

@ -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,

View File

@ -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()

View File

@ -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",
]