From 4a343754498eb7fd9a980f7e7f69bb01a8773349 Mon Sep 17 00:00:00 2001 From: Devin Ragotzy Date: Sun, 26 Jul 2020 19:18:28 -0400 Subject: [PATCH] Support multiple attribute arguments in ruma_event attribute (#161) * Add parsing to allow ruma_event attribute to accept mutli args * fixup! Add parsing to allow ruma_event attribute to accept mutli args * Refactor MetaAttrs::parse and resolve review issues --- ruma-events-macros/src/event_content.rs | 43 ++++++++++++++++++------- ruma-events/src/room/aliases.rs | 3 +- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/ruma-events-macros/src/event_content.rs b/ruma-events-macros/src/event_content.rs index a4226dc9..5cd86d3d 100644 --- a/ruma-events-macros/src/event_content.rs +++ b/ruma-events-macros/src/event_content.rs @@ -56,6 +56,25 @@ impl Parse for EventMeta { } } +struct MetaAttrs(Vec); + +impl MetaAttrs { + fn is_custom(&self) -> bool { + self.0.iter().any(|a| a == &EventMeta::CustomRedacted) + } + + fn get_event_type(&self) -> Option<&LitStr> { + self.0.iter().find_map(|a| a.get_event_type()) + } +} + +impl Parse for MetaAttrs { + fn parse(input: ParseStream) -> syn::Result { + let attrs = syn::punctuated::Punctuated::::parse_terminated(input)?; + Ok(Self(attrs.into_iter().collect())) + } +} + /// Create an `EventContent` implementation for a struct. pub fn expand_event_content(input: &DeriveInput, emit_redacted: bool) -> syn::Result { let ident = &input.ident; @@ -64,7 +83,7 @@ pub fn expand_event_content(input: &DeriveInput, emit_redacted: bool) -> syn::Re .attrs .iter() .filter(|attr| attr.path.is_ident("ruma_event")) - .map(|attr| attr.parse_args::()) + .map(|attr| attr.parse_args::()) .collect::>>()?; let event_type = content_attr.iter().find_map(|a| a.get_event_type()).ok_or_else(|| { @@ -75,7 +94,7 @@ pub fn expand_event_content(input: &DeriveInput, emit_redacted: bool) -> syn::Re syn::Error::new(Span::call_site(), msg) })?; - let redacted = if emit_redacted && needs_redacted(input) { + let redacted = if emit_redacted && needs_redacted(&content_attr) { let doc = format!("The payload for a redacted `{}`", ident); let redacted_ident = format_ident!("Redacted{}", ident); let kept_redacted_fields = if let syn::Data::Struct(syn::DataStruct { @@ -238,7 +257,7 @@ pub fn expand_message_event_content(input: &DeriveInput) -> syn::Result syn::Result TokenStrea } } -fn needs_redacted(input: &DeriveInput) -> bool { - input - .attrs - .iter() - .flat_map(|a| a.parse_args::().ok()) - .find(|a| a == &EventMeta::CustomRedacted) - .is_none() +fn needs_redacted(input: &[MetaAttrs]) -> 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 + // needs a redacted struct generated. + !input.iter().any(|a| a.is_custom()) +} + +fn needs_redacted_from_input(input: &DeriveInput) -> bool { + !input.attrs.iter().flat_map(|a| a.parse_args::().ok()).any(|a| a.is_custom()) } diff --git a/ruma-events/src/room/aliases.rs b/ruma-events/src/room/aliases.rs index 4fd42c40..9c0095f4 100644 --- a/ruma-events/src/room/aliases.rs +++ b/ruma-events/src/room/aliases.rs @@ -15,8 +15,7 @@ pub type AliasesEvent = StateEvent; /// The payload for `AliasesEvent`. #[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)] #[non_exhaustive] -#[ruma_event(type = "m.room.aliases")] -#[ruma_event(custom_redacted)] +#[ruma_event(type = "m.room.aliases", custom_redacted)] pub struct AliasesEventContent { /// A list of room aliases. pub aliases: Vec,