macros: Ensure event content types are structs

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

View File

@ -145,19 +145,31 @@ pub fn expand_event_content(
} }
}; };
let ident = &input.ident;
let fields = match &input.data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => fields,
_ => {
return Err(syn::Error::new(
Span::call_site(),
"event content types need to be structs",
));
}
};
// We only generate redacted content structs for state and message-like events // We only generate redacted content structs for state and message-like events
let redacted_event_content = needs_redacted(&content_attr, event_kind) let redacted_event_content = needs_redacted(&content_attr, event_kind)
.then(|| generate_redacted_event_content(input, event_type, ruma_common, event_kind)) .then(|| {
generate_redacted_event_content(ident, fields, event_type, ruma_common, event_kind)
})
.transpose()?; .transpose()?;
let event_content_impl = generate_event_content_impl(&input.ident, event_type, ruma_common); let event_content_impl = generate_event_content_impl(ident, event_type, ruma_common);
let static_event_content_impl = event_kind.map(|k| { let static_event_content_impl = event_kind
generate_static_event_content_impl(&input.ident, k, false, event_type, ruma_common) .map(|k| generate_static_event_content_impl(ident, k, false, event_type, ruma_common));
});
let marker_trait_impl = let marker_trait_impl =
event_kind.map(|k| generate_marker_trait_impl(k, &input.ident, ruma_common)).transpose()?; event_kind.map(|k| generate_marker_trait_impl(k, ident, ruma_common)).transpose()?;
let type_aliases = event_kind let type_aliases = event_kind
.map(|k| generate_event_type_aliases(k, &input.ident, &event_type.value(), ruma_common)) .map(|k| generate_event_type_aliases(k, ident, &event_type.value(), ruma_common))
.transpose()?; .transpose()?;
Ok(quote! { Ok(quote! {
@ -170,7 +182,8 @@ pub fn expand_event_content(
} }
fn generate_redacted_event_content( fn generate_redacted_event_content(
input: &DeriveInput, ident: &Ident,
fields: &syn::Fields,
event_type: &LitStr, event_type: &LitStr,
ruma_common: &TokenStream, ruma_common: &TokenStream,
event_kind: Option<EventKind>, event_kind: Option<EventKind>,
@ -178,44 +191,39 @@ fn generate_redacted_event_content(
let serde = quote! { #ruma_common::exports::serde }; let serde = quote! { #ruma_common::exports::serde };
let serde_json = quote! { #ruma_common::exports::serde_json }; let serde_json = quote! { #ruma_common::exports::serde_json };
let ident = &input.ident;
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: Vec<syn::Field> = if let syn::Data::Struct(st) = &input.data { let kept_redacted_fields: Vec<_> = fields
st.fields .iter()
.iter() .map(|f| {
.map(|f| { let mut keep_field = false;
let mut keep_field = false; let attrs = f
let attrs = f .attrs
.attrs .iter()
.iter() .map(|a| -> syn::Result<_> {
.map(|a| -> syn::Result<_> { if a.path.is_ident("ruma_event") {
if a.path.is_ident("ruma_event") { if let EventMeta::SkipRedaction = a.parse_args()? {
if let EventMeta::SkipRedaction = a.parse_args()? { keep_field = true;
keep_field = true;
}
// don't re-emit our `ruma_event` attributes
Ok(None)
} else {
Ok(Some(a.clone()))
} }
})
.filter_map(Result::transpose)
.collect::<syn::Result<_>>()?;
if keep_field { // don't re-emit our `ruma_event` attributes
Ok(Some(syn::Field { attrs, ..f.clone() })) Ok(None)
} else { } else {
Ok(None) Ok(Some(a.clone()))
} }
}) })
.filter_map(Result::transpose) .filter_map(Result::transpose)
.collect::<syn::Result<_>>()? .collect::<syn::Result<_>>()?;
} else {
vec![] if keep_field {
}; Ok(Some(syn::Field { attrs, ..f.clone() }))
} else {
Ok(None)
}
})
.filter_map(Result::transpose)
.collect::<syn::Result<_>>()?;
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);