events: Refactor EventContent derive code

This commit is contained in:
Jonas Platte 2021-08-11 19:26:54 +02:00
parent 11fea54173
commit a30279b83f
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67

View File

@ -103,12 +103,6 @@ pub fn expand_event_content(
input: &DeriveInput, input: &DeriveInput,
ruma_events: &TokenStream, ruma_events: &TokenStream,
) -> syn::Result<TokenStream> { ) -> syn::Result<TokenStream> {
let ruma_identifiers = quote! { #ruma_events::exports::ruma_identifiers };
let serde = quote! { #ruma_events::exports::serde };
let serde_json = quote! { #ruma_events::exports::serde_json };
let ident = &input.ident;
let content_attr = input let content_attr = input
.attrs .attrs
.iter() .iter()
@ -150,10 +144,37 @@ pub fn expand_event_content(
}; };
// We only generate redacted content structs for state and message events // We only generate redacted content structs for state and message events
let redacted = if 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_events, event_kind))
.transpose()?;
let event_content_impl = generate_event_content_impl(&input.ident, event_type, ruma_events);
let marker_trait_impl =
event_kind.map(|k| generate_marker_trait_impl(k, &input.ident, ruma_events)).transpose()?;
Ok(quote! {
#redacted_event_content
#event_content_impl
#marker_trait_impl
})
}
fn generate_redacted_event_content(
input: &DeriveInput,
event_type: &LitStr,
ruma_events: &TokenStream,
event_kind: Option<&EventKind>,
) -> Result<TokenStream, syn::Error> {
let ruma_identifiers = quote! { #ruma_events::exports::ruma_identifiers };
let serde = quote! { #ruma_events::exports::serde };
let serde_json = quote! { #ruma_events::exports::serde_json };
let ident = &input.ident;
let doc = format!("The payload for a redacted `{}`", ident); let doc = format!("The payload for a redacted `{}`", ident);
let redacted_ident = format_ident!("Redacted{}", ident); let redacted_ident = format_ident!("Redacted{}", ident);
let kept_redacted_fields = if let syn::Data::Struct(syn::DataStruct {
let kept_redacted_fields =
if let syn::Data::Struct(syn::DataStruct {
fields: syn::Fields::Named(syn::FieldsNamed { named, .. }), fields: syn::Fields::Named(syn::FieldsNamed { named, .. }),
.. ..
}) = &input.data }) = &input.data
@ -191,12 +212,9 @@ pub fn expand_event_content(
} else { } else {
vec![] 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);
// redacted_fields allows one to declare an empty redacted event without braces,
// otherwise `RedactedWhateverEventContent {}` is needed.
// The redacted_return is used in `EventContent::redacted` which only returns
// zero sized types (unit structs).
let (redacted_fields, redacted_return) = if kept_redacted_fields.is_empty() { let (redacted_fields, redacted_return) = if kept_redacted_fields.is_empty() {
(quote! { ; }, quote! { Ok(#redacted_ident {}) }) (quote! { ; }, quote! { Ok(#redacted_ident {}) })
} else { } else {
@ -212,19 +230,13 @@ pub fn expand_event_content(
) )
}; };
let has_deserialize_fields = if kept_redacted_fields.is_empty() { let (has_deserialize_fields, has_serialize_fields) = if kept_redacted_fields.is_empty() {
quote! { #ruma_events::HasDeserializeFields::False } (quote! { #ruma_events::HasDeserializeFields::False }, quote! { false })
} else { } else {
quote! { #ruma_events::HasDeserializeFields::True } (quote! { #ruma_events::HasDeserializeFields::True }, quote! { true })
}; };
let has_serialize_fields = if kept_redacted_fields.is_empty() { let constructor = kept_redacted_fields.is_empty().then(|| {
quote! { false }
} else {
quote! { true }
};
let initializer = if kept_redacted_fields.is_empty() {
let doc = format!("Creates an empty {}.", redacted_ident); let doc = format!("Creates an empty {}.", redacted_ident);
quote! { quote! {
impl #redacted_ident { impl #redacted_ident {
@ -234,9 +246,7 @@ pub fn expand_event_content(
} }
} }
} }
} else { });
TokenStream::new()
};
let redacted_event_content = let redacted_event_content =
generate_event_content_impl(&redacted_ident, event_type, ruma_events); generate_event_content_impl(&redacted_ident, event_type, ruma_events);
@ -253,7 +263,7 @@ pub fn expand_event_content(
_ => TokenStream::new(), _ => TokenStream::new(),
}; };
quote! { Ok(quote! {
// this is the non redacted event content's impl // this is the non redacted event content's impl
#[automatically_derived] #[automatically_derived]
impl #ruma_events::RedactContent for #ident { impl #ruma_events::RedactContent for #ident {
@ -271,7 +281,7 @@ pub fn expand_event_content(
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct #redacted_ident #redacted_fields pub struct #redacted_ident #redacted_fields
#initializer #constructor
#redacted_event_content #redacted_event_content
@ -297,24 +307,10 @@ pub fn expand_event_content(
} }
#redacted_event_content_derive #redacted_event_content_derive
}
} else {
TokenStream::new()
};
let event_content_derive =
event_kind.map(|k| generate_event_content_derive(k, ident, ruma_events)).transpose()?;
let event_content = generate_event_content_impl(ident, event_type, ruma_events);
Ok(quote! {
#event_content
#event_content_derive
#redacted
}) })
} }
fn generate_event_content_derive( fn generate_marker_trait_impl(
event_kind: &EventKind, event_kind: &EventKind,
ident: &Ident, ident: &Ident,
ruma_events: &TokenStream, ruma_events: &TokenStream,