From 392cf23d4b34be95a4c72a9a140d2cfae2d7e570 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sat, 29 Jan 2022 02:08:33 +0100 Subject: [PATCH] events: Don't store data of unknown events in enums --- crates/ruma-events-macros/src/event_enum.rs | 50 +++----------------- crates/ruma-events/src/custom.rs | 51 +++++++++++++++++++++ crates/ruma-events/src/lib.rs | 5 +- 3 files changed, 59 insertions(+), 47 deletions(-) diff --git a/crates/ruma-events-macros/src/event_enum.rs b/crates/ruma-events-macros/src/event_enum.rs index dd9b2567..b2f15013 100644 --- a/crates/ruma-events-macros/src/event_enum.rs +++ b/crates/ruma-events-macros/src/event_enum.rs @@ -71,21 +71,6 @@ fn expand_event_enum( let variant_decls = variants.iter().map(|v| v.decl()); let content: Vec<_> = events.iter().map(|event| to_event_path(event, kind, var, ruma_events)).collect(); - let custom_variant = if var.is_redacted() { - quote! { - /// A redacted event not defined by the Matrix specification - #[doc(hidden)] - _Custom( - #ruma_events::#event_struct<#ruma_events::custom::RedactedCustomEventContent>, - ), - } - } else { - quote! { - /// An event not defined by the Matrix specification - #[doc(hidden)] - _Custom(#ruma_events::#event_struct<#ruma_events::custom::CustomEventContent>), - } - }; let deserialize_impl = expand_deserialize_impl(kind, var, events, variants, ruma_events); let field_accessor_impl = expand_accessor_methods(kind, var, variants, ruma_events); @@ -102,7 +87,9 @@ fn expand_event_enum( #[doc = #events] #variant_decls(#content), )* - #custom_variant + /// An event not defined by the Matrix specification + #[doc(hidden)] + _Custom(#ruma_events::#event_struct<#ruma_events::custom::_CustomEventContent>), } #deserialize_impl @@ -122,7 +109,6 @@ fn expand_deserialize_impl( let serde_json = quote! { #ruma_events::exports::serde_json }; let ident = kind.to_event_enum_ident(var); - let event_struct = kind.to_event_ident(var); let variant_attrs = variants.iter().map(|v| { let attrs = &v.attrs; @@ -131,31 +117,6 @@ fn expand_deserialize_impl( let self_variants = variants.iter().map(|v| v.ctor(quote! { Self })); let content = events.iter().map(|event| to_event_path(event, kind, var, ruma_events)); - let custom_deserialize = if var.is_redacted() { - quote! { - event => { - let event = #serde_json::from_str::<#ruma_events::#event_struct< - #ruma_events::custom::RedactedCustomEventContent, - >>(json.get()) - .map_err(D::Error::custom)?; - - Ok(Self::_Custom(event)) - }, - } - } else { - quote! { - 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)) - }, - } - }; - quote! { impl<'de> #serde::de::Deserialize<'de> for #ident { fn deserialize(deserializer: D) -> Result @@ -176,7 +137,10 @@ fn expand_deserialize_impl( Ok(#self_variants(event)) }, )* - #custom_deserialize + _ => { + let event = #serde_json::from_str(json.get()).map_err(D::Error::custom)?; + Ok(Self::_Custom(event)) + }, } } } diff --git a/crates/ruma-events/src/custom.rs b/crates/ruma-events/src/custom.rs index 1b4de043..d0c02043 100644 --- a/crates/ruma-events/src/custom.rs +++ b/crates/ruma-events/src/custom.rs @@ -97,3 +97,54 @@ impl RedactedEventContent for RedactedCustomEventContent { impl RedactedMessageEventContent for RedactedCustomEventContent {} impl RedactedStateEventContent for RedactedCustomEventContent {} + +/// A custom event's type. Used for event enum `_Custom` variants. +#[doc(hidden)] +// FIXME: Serialize shouldn't be required here, but it's currently a supertrait of EventContent +#[derive(Clone, Debug, Serialize)] +#[allow(clippy::exhaustive_structs)] +pub struct _CustomEventContent { + #[serde(skip)] + event_type: Box, +} + +impl RedactContent for _CustomEventContent { + type Redacted = Self; + + fn redact(self, _: &RoomVersionId) -> Self { + self + } +} + +impl EventContent for _CustomEventContent { + fn event_type(&self) -> &str { + &self.event_type + } + + fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result { + Ok(Self { event_type: event_type.into() }) + } +} + +impl RedactedEventContent for _CustomEventContent { + fn empty(event_type: &str) -> serde_json::Result { + Ok(Self { event_type: event_type.into() }) + } + + fn has_serialize_fields(&self) -> bool { + false + } + + fn has_deserialize_fields() -> HasDeserializeFields { + HasDeserializeFields::False + } +} + +impl GlobalAccountDataEventContent for _CustomEventContent {} +impl RoomAccountDataEventContent for _CustomEventContent {} +impl ToDeviceEventContent for _CustomEventContent {} +impl EphemeralRoomEventContent for _CustomEventContent {} +impl MessageEventContent for _CustomEventContent {} +impl StateEventContent for _CustomEventContent {} +impl RedactedMessageEventContent for _CustomEventContent {} +impl RedactedStateEventContent for _CustomEventContent {} diff --git a/crates/ruma-events/src/lib.rs b/crates/ruma-events/src/lib.rs index d6e1bf27..300c3a12 100644 --- a/crates/ruma-events/src/lib.rs +++ b/crates/ruma-events/src/lib.rs @@ -411,10 +411,7 @@ pub struct PrivOwnedStr(Box); /// only be created by deserializing from an unknown event type. #[doc(hidden)] #[allow(clippy::ptr_arg)] -pub fn serialize_custom_event_error( - _: &PrivOwnedStr, - _: S, -) -> Result { +pub fn serialize_custom_event_error(_: &T, _: S) -> Result { Err(serde::ser::Error::custom( "Failed to serialize event [content] enum: Unknown event type.\n\ To send custom events, turn them into `Raw` by going through