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,39 +182,37 @@ 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 {
// this is to validate the `#[ruma_event(skip_redaction)]` attribute
st.fields st.fields
.iter() .iter()
.flat_map(|f| &f.attrs) .map(|f| {
.filter(|a| a.path.is_ident("ruma_event")) let mut keep_field = false;
.find_map(|a| { let attrs = f
if let Err(e) = a.parse_args::<EventMeta>() { .attrs
Some(Err(e))
} else {
None
}
})
.unwrap_or(Ok(()))?;
let mut fields: Vec<_> = st
.fields
.iter() .iter()
.filter(|f| { .map(|a| -> syn::Result<_> {
matches!( if a.path.is_ident("ruma_event") {
f.attrs.iter().find_map(|a| a.parse_args::<EventMeta>().ok()), if let EventMeta::SkipRedaction = a.parse_args()? {
Some(EventMeta::SkipRedaction) keep_field = true;
) }
})
.cloned()
.collect();
// don't re-emit our `ruma_event` attributes // don't re-emit our `ruma_event` attributes
for f in &mut fields { Ok(None)
f.attrs.retain(|a| !a.path.is_ident("ruma_event")); } else {
Ok(Some(a.clone()))
} }
fields })
.filter_map(Result::transpose)
.collect::<syn::Result<_>>()?;
if keep_field {
Ok(Some(syn::Field { attrs, ..f.clone() }))
} else {
Ok(None)
}
})
.filter_map(Result::transpose)
.collect::<syn::Result<_>>()?
} else { } else {
vec![] vec![]
}; };