From cd2f011fb3e891f0ff783a18afa39ec3b7c42acd Mon Sep 17 00:00:00 2001 From: Devin R Date: Fri, 17 Jul 2020 07:23:38 -0400 Subject: [PATCH] Add AnyPossiblyRedacted* enums to event_enum! code-gen --- ruma-events-macros/src/event_enum.rs | 59 ++++++++++++++++++++++++++++ ruma-events/src/lib.rs | 13 +++--- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/ruma-events-macros/src/event_enum.rs b/ruma-events-macros/src/event_enum.rs index 31e7f23f..a751f658 100644 --- a/ruma-events-macros/src/event_enum.rs +++ b/ruma-events-macros/src/event_enum.rs @@ -129,6 +129,8 @@ fn expand_any_with_deser( } }; + let redacted_enum = generate_redacted_enum(kind, var); + let field_accessor_impl = accessor_methods(kind, var, &variants); let redact_impl = generate_redact(&ident, kind, var, &variants); @@ -141,9 +143,66 @@ fn expand_any_with_deser( #redact_impl #event_deserialize_impl + + #redacted_enum }) } +fn generate_redacted_enum(kind: &EventKind, var: &EventKindVariation) -> Option { + if let EventKind::State(_) | EventKind::Message(_) = kind { + let ident = format_ident!("AnyPossiblyRedacted{}", kind.to_event_ident(var)?); + + let (regular_enum_ident, redacted_enum_ident) = inner_enum_idents(kind, var)?; + Some(quote! { + /// An enum that holds either regular un-redacted events or redacted events. + #[derive(Clone, Debug, ::serde::Serialize)] + #[serde(untagged)] + pub enum #ident { + /// An un-redacted event. + Regular(#regular_enum_ident), + /// A redacted event. + Redacted(#redacted_enum_ident), + } + + impl<'de> ::serde::de::Deserialize<'de> for #ident { + fn deserialize(deserializer: D) -> Result + where + D: ::serde::de::Deserializer<'de>, + { + let json = Box::<::serde_json::value::RawValue>::deserialize(deserializer)?; + let ::ruma_events::EventDeHelper { unsigned, .. } = ::ruma_events::from_raw_json_value(&json)?; + Ok(match unsigned { + Some(unsigned) if unsigned.redacted_because.is_some() => { + Self::Redacted(::ruma_events::from_raw_json_value(&json)?) + } + _ => Self::Regular(::ruma_events::from_raw_json_value(&json)?), + }) + } + } + }) + } else { + None + } +} + +fn inner_enum_idents(kind: &EventKind, var: &EventKindVariation) -> Option<(Ident, Ident)> { + match var { + EventKindVariation::Full => Some(( + kind.to_event_enum_ident(var)?, + kind.to_event_enum_ident(&EventKindVariation::Redacted)?, + )), + EventKindVariation::Sync => Some(( + kind.to_event_enum_ident(var)?, + kind.to_event_enum_ident(&EventKindVariation::RedactedSync)?, + )), + EventKindVariation::Stripped => Some(( + kind.to_event_enum_ident(var)?, + kind.to_event_enum_ident(&EventKindVariation::RedactedStripped)?, + )), + _ => None, + } +} + fn generate_redact( ident: &Ident, kind: &EventKind, diff --git a/ruma-events/src/lib.rs b/ruma-events/src/lib.rs index cea35b00..9c97f447 100644 --- a/ruma-events/src/lib.rs +++ b/ruma-events/src/lib.rs @@ -165,11 +165,14 @@ pub use self::{ algorithm::Algorithm, enums::{ AnyBasicEvent, AnyBasicEventContent, AnyEphemeralRoomEvent, AnyEphemeralRoomEventContent, - AnyEvent, AnyMessageEvent, AnyMessageEventContent, AnyRedactedMessageEvent, - AnyRedactedStateEvent, AnyRedactedStrippedStateEvent, AnyRedactedSyncMessageEvent, - AnyRedactedSyncStateEvent, AnyRoomEvent, AnyStateEvent, AnyStateEventContent, - AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, AnySyncMessageEvent, AnySyncRoomEvent, - AnySyncStateEvent, AnyToDeviceEvent, AnyToDeviceEventContent, + AnyEvent, AnyMessageEvent, AnyMessageEventContent, AnyPossiblyRedactedMessageEvent, + AnyPossiblyRedactedStateEvent, AnyPossiblyRedactedStrippedStateEvent, + AnyPossiblyRedactedSyncMessageEvent, AnyPossiblyRedactedSyncStateEvent, + AnyRedactedMessageEvent, AnyRedactedStateEvent, AnyRedactedStrippedStateEvent, + AnyRedactedSyncMessageEvent, AnyRedactedSyncStateEvent, AnyRoomEvent, AnyStateEvent, + AnyStateEventContent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, + AnySyncMessageEvent, AnySyncRoomEvent, AnySyncStateEvent, AnyToDeviceEvent, + AnyToDeviceEventContent, }, error::{FromStrError, InvalidInput}, event_kinds::{