macros: Only iterate fields once in EventContent derive

This commit is contained in:
Jonas Platte 2022-03-14 15:11:30 +01:00
parent 46bab5cca6
commit 0b10151bcb
No known key found for this signature in database
GPG Key ID: BBA95679259D342F

View File

@ -182,42 +182,40 @@ fn generate_redacted_event_content(
let doc = format!("Redacted form of [`{}`]", ident); let doc = format!("Redacted form of [`{}`]", ident);
let redacted_ident = format_ident!("Redacted{}", ident); let redacted_ident = format_ident!("Redacted{}", ident);
let kept_redacted_fields = let kept_redacted_fields: Vec<syn::Field> = if let syn::Data::Struct(st) = &input.data {
if let syn::Data::Struct(st) = &input.data { st.fields
// this is to validate the `#[ruma_event(skip_redaction)]` attribute .iter()
st.fields .map(|f| {
.iter() let mut keep_field = false;
.flat_map(|f| &f.attrs) let attrs = f
.filter(|a| a.path.is_ident("ruma_event")) .attrs
.find_map(|a| { .iter()
if let Err(e) = a.parse_args::<EventMeta>() { .map(|a| -> syn::Result<_> {
Some(Err(e)) if a.path.is_ident("ruma_event") {
} else { if let EventMeta::SkipRedaction = a.parse_args()? {
None keep_field = true;
} }
})
.unwrap_or(Ok(()))?;
let mut fields: Vec<_> = st // don't re-emit our `ruma_event` attributes
.fields Ok(None)
.iter() } else {
.filter(|f| { Ok(Some(a.clone()))
matches!( }
f.attrs.iter().find_map(|a| a.parse_args::<EventMeta>().ok()), })
Some(EventMeta::SkipRedaction) .filter_map(Result::transpose)
) .collect::<syn::Result<_>>()?;
})
.cloned()
.collect();
// don't re-emit our `ruma_event` attributes if keep_field {
for f in &mut fields { Ok(Some(syn::Field { attrs, ..f.clone() }))
f.attrs.retain(|a| !a.path.is_ident("ruma_event")); } else {
} Ok(None)
fields }
} else { })
vec![] .filter_map(Result::transpose)
}; .collect::<syn::Result<_>>()?
} else {
vec![]
};
let redaction_struct_fields = kept_redacted_fields.iter().flat_map(|f| &f.ident); let redaction_struct_fields = kept_redacted_fields.iter().flat_map(|f| &f.ident);