From 0b10151bcbaf58ce0b587110d35a84316b9b1c44 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 14 Mar 2022 15:11:30 +0100 Subject: [PATCH] macros: Only iterate fields once in EventContent derive --- .../ruma-macros/src/events/event_content.rs | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/crates/ruma-macros/src/events/event_content.rs b/crates/ruma-macros/src/events/event_content.rs index ac2e8395..ea562627 100644 --- a/crates/ruma-macros/src/events/event_content.rs +++ b/crates/ruma-macros/src/events/event_content.rs @@ -182,42 +182,40 @@ fn generate_redacted_event_content( let doc = format!("Redacted form of [`{}`]", ident); let redacted_ident = format_ident!("Redacted{}", ident); - let kept_redacted_fields = - if let syn::Data::Struct(st) = &input.data { - // this is to validate the `#[ruma_event(skip_redaction)]` attribute - st.fields - .iter() - .flat_map(|f| &f.attrs) - .filter(|a| a.path.is_ident("ruma_event")) - .find_map(|a| { - if let Err(e) = a.parse_args::() { - Some(Err(e)) - } else { - None - } - }) - .unwrap_or(Ok(()))?; + let kept_redacted_fields: Vec = if let syn::Data::Struct(st) = &input.data { + st.fields + .iter() + .map(|f| { + let mut keep_field = false; + let attrs = f + .attrs + .iter() + .map(|a| -> syn::Result<_> { + if a.path.is_ident("ruma_event") { + if let EventMeta::SkipRedaction = a.parse_args()? { + keep_field = true; + } - let mut fields: Vec<_> = st - .fields - .iter() - .filter(|f| { - matches!( - f.attrs.iter().find_map(|a| a.parse_args::().ok()), - Some(EventMeta::SkipRedaction) - ) - }) - .cloned() - .collect(); + // don't re-emit our `ruma_event` attributes + Ok(None) + } else { + Ok(Some(a.clone())) + } + }) + .filter_map(Result::transpose) + .collect::>()?; - // don't re-emit our `ruma_event` attributes - for f in &mut fields { - f.attrs.retain(|a| !a.path.is_ident("ruma_event")); - } - fields - } else { - vec![] - }; + if keep_field { + Ok(Some(syn::Field { attrs, ..f.clone() })) + } else { + Ok(None) + } + }) + .filter_map(Result::transpose) + .collect::>()? + } else { + vec![] + }; let redaction_struct_fields = kept_redacted_fields.iter().flat_map(|f| &f.ident);