From 9445e8756afab050addd487443dcca2e262ce9a7 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 11 Aug 2021 20:30:17 +0200 Subject: [PATCH] events: Derive / implement StaticEventContent for all relevant types --- .../ruma-events-macros/src/event_content.rs | 40 ++++++++++++++++++- crates/ruma-events/CHANGELOG.md | 5 +++ crates/ruma-events/src/lib.rs | 3 ++ crates/ruma-events/src/presence.rs | 7 ++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/crates/ruma-events-macros/src/event_content.rs b/crates/ruma-events-macros/src/event_content.rs index 57214003..6bf9d680 100644 --- a/crates/ruma-events-macros/src/event_content.rs +++ b/crates/ruma-events-macros/src/event_content.rs @@ -149,12 +149,16 @@ pub fn expand_event_content( .transpose()?; let event_content_impl = generate_event_content_impl(&input.ident, event_type, ruma_events); + let static_event_content_impl = event_kind.map(|k| { + generate_static_event_content_impl(&input.ident, k, false, event_type, ruma_events) + }); let marker_trait_impl = event_kind.map(|k| generate_marker_trait_impl(k, &input.ident, ruma_events)).transpose()?; Ok(quote! { #redacted_event_content #event_content_impl + #static_event_content_impl #marker_trait_impl }) } @@ -251,7 +255,7 @@ fn generate_redacted_event_content( let redacted_event_content = generate_event_content_impl(&redacted_ident, event_type, ruma_events); - let redacted_event_content_derive = match event_kind { + let marker_trait_impl = match event_kind { Some(EventKind::Message) => quote! { #[automatically_derived] impl #ruma_events::RedactedMessageEventContent for #redacted_ident {} @@ -263,6 +267,10 @@ fn generate_redacted_event_content( _ => TokenStream::new(), }; + let static_event_content_impl = event_kind.map(|k| { + generate_static_event_content_impl(&redacted_ident, k, true, event_type, ruma_events) + }); + Ok(quote! { // this is the non redacted event content's impl #[automatically_derived] @@ -306,7 +314,8 @@ fn generate_redacted_event_content( } } - #redacted_event_content_derive + #static_event_content_impl + #marker_trait_impl }) } @@ -368,6 +377,33 @@ fn generate_event_content_impl( } } +fn generate_static_event_content_impl( + ident: &Ident, + event_kind: &EventKind, + redacted: bool, + event_type: &LitStr, + ruma_events: &TokenStream, +) -> TokenStream { + let event_kind = match event_kind { + EventKind::GlobalAccountData => quote! { GlobalAccountData }, + EventKind::RoomAccountData => quote! { RoomAccountData }, + EventKind::Ephemeral => quote! { EphemeralRoomData }, + EventKind::Message => quote! { Message { redacted: #redacted } }, + EventKind::State => quote! { State { redacted: #redacted } }, + EventKind::ToDevice => quote! { ToDevice }, + EventKind::Redaction | EventKind::Presence | EventKind::Decrypted => { + unreachable!("not a valid event content kind") + } + }; + + quote! { + impl #ruma_events::StaticEventContent for #ident { + const KIND: #ruma_events::EventKind = #ruma_events::EventKind::#event_kind; + const TYPE: &'static ::std::primitive::str = #event_type; + } + } +} + fn needs_redacted(input: &[MetaAttrs], event_kind: Option<&EventKind>) -> bool { // `is_custom` means that the content struct does not need a generated // redacted struct also. If no `custom_redacted` attrs are found the content diff --git a/crates/ruma-events/CHANGELOG.md b/crates/ruma-events/CHANGELOG.md index c6d8cb7a..a39358c1 100644 --- a/crates/ruma-events/CHANGELOG.md +++ b/crates/ruma-events/CHANGELOG.md @@ -14,6 +14,11 @@ Breaking changes: * It doesn't have the `relates_to` field `EncryptedEventContent` has * Upgrade dependencies +Improvements: + +* Add the `StaticEventContent` trait for abstracting over event content struct + types (with a type known at compile-time) + # 0.24.0 Yanked, was released too early missing another important breaking change. diff --git a/crates/ruma-events/src/lib.rs b/crates/ruma-events/src/lib.rs index 1e361f40..5f81e9bd 100644 --- a/crates/ruma-events/src/lib.rs +++ b/crates/ruma-events/src/lib.rs @@ -407,6 +407,9 @@ pub enum EventKind { /// To-device event kind. ToDevice, + + /// Presence event kind. + Presence, } /// `HasDeserializeFields` is used in the code generated by the `Event` derive diff --git a/crates/ruma-events/src/presence.rs b/crates/ruma-events/src/presence.rs index b278bf45..85014529 100644 --- a/crates/ruma-events/src/presence.rs +++ b/crates/ruma-events/src/presence.rs @@ -8,6 +8,8 @@ use ruma_events_macros::{Event, EventContent}; use ruma_identifiers::{MxcUri, UserId}; use serde::{Deserialize, Serialize}; +use crate::{EventKind, StaticEventContent}; + /// Presence event. #[derive(Clone, Debug, Event)] #[allow(clippy::exhaustive_structs)] @@ -71,6 +73,11 @@ impl PresenceEventContent { } } +impl StaticEventContent for PresenceEventContent { + const KIND: EventKind = EventKind::Presence; + const TYPE: &'static str = "m.presence"; +} + #[cfg(test)] mod tests { use js_int::uint;