From 4423275ce27b7d26b5418d4fda5bd74c39bd9697 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Wed, 19 Jun 2019 22:40:58 -0700 Subject: [PATCH] Implement RoomEvent and StateEvent when applicable. --- src/gen.rs | 61 ++++++++++++++++++++++++++++++++++++- src/parse.rs | 1 + tests/ruma_events_macros.rs | 31 +++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/gen.rs b/src/gen.rs index 894d96db..93c858e3 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -30,7 +30,6 @@ pub struct RumaEvent { fields: Vec, /// The kind of event. - #[allow(dead_code)] kind: EventKind, /// The name of the event. @@ -199,6 +198,62 @@ impl ToTokens for RumaEvent { serialize_field_calls.push(serialize_field_call); } + let impl_room_event = match self.kind { + EventKind::RoomEvent | EventKind::StateEvent => { + quote! { + impl crate::RoomEvent for #name { + /// The unique identifier for the event. + fn event_id(&self) -> &ruma_identifiers::EventId { + &self.event_id + } + + /// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this event was + /// sent. + fn origin_server_ts(&self) -> js_int::UInt { + self.origin_server_ts + } + + /// The unique identifier for the room associated with this event. + /// + /// This can be `None` if the event came from a context where there is + /// no ambiguity which room it belongs to, like a `/sync` response for example. + fn room_id(&self) -> Option<&ruma_identifiers::RoomId> { + self.room_id.as_ref() + } + + /// The unique identifier for the user who sent this event. + fn sender(&self) -> &ruma_identifiers::UserId { + &self.sender + } + + /// Additional key-value pairs not signed by the homeserver. + fn unsigned(&self) -> Option<&serde_json::Value> { + self.unsigned.as_ref() + } + } + } + } + _ => TokenStream::new(), + }; + + let impl_state_event = if self.kind == EventKind::StateEvent { + quote! { + impl crate::StateEvent for #name { + /// The previous content for this state key, if any. + fn prev_content(&self) -> Option<&Self::Content> { + self.prev_content.as_ref() + } + + /// A key that determines which piece of room state the event represents. + fn state_key(&self) -> &str { + &self.state_key + } + } + } + } else { + TokenStream::new() + }; + let output = quote!( #(#attrs)* #[derive(Clone, Debug)] @@ -248,6 +303,10 @@ impl ToTokens for RumaEvent { } } + #impl_room_event + + #impl_state_event + /// "Raw" versions of the event and its content which implement `serde::Deserialize`. mod raw { use super::*; diff --git a/src/parse.rs b/src/parse.rs index 5077191c..266f8756 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -167,6 +167,7 @@ impl Parse for RumaEventInput { /// Which kind of event is being generated. /// /// Determined by the `kind` field in the macro body. +#[derive(PartialEq)] pub enum EventKind { /// A basic event. Event, diff --git a/tests/ruma_events_macros.rs b/tests/ruma_events_macros.rs index e8257c6d..c3be78f7 100644 --- a/tests/ruma_events_macros.rs +++ b/tests/ruma_events_macros.rs @@ -35,6 +35,37 @@ where } } +/// An event within the context of a room. +pub trait RoomEvent: Event { + /// The unique identifier for the event. + fn event_id(&self) -> &ruma_identifiers::EventId; + + /// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this event was + /// sent. + fn origin_server_ts(&self) -> js_int::UInt; + + /// The unique identifier for the room associated with this event. + /// + /// This can be `None` if the event came from a context where there is + /// no ambiguity which room it belongs to, like a `/sync` response for example. + fn room_id(&self) -> Option<&ruma_identifiers::RoomId>; + + /// The unique identifier for the user who sent this event. + fn sender(&self) -> &ruma_identifiers::UserId; + + /// Additional key-value pairs not signed by the homeserver. + fn unsigned(&self) -> Option<&serde_json::Value>; +} + +/// An event that describes persistent state about a room. +pub trait StateEvent: RoomEvent { + /// The previous content for this state key, if any. + fn prev_content(&self) -> Option<&Self::Content>; + + /// A key that determines which piece of room state the event represents. + fn state_key(&self) -> &str; +} + pub struct InvalidEvent; impl From for InvalidEvent {