Generate EventKind/Variation pair from Event derive input
This commit is contained in:
parent
4b9fdcb189
commit
a39c0106d4
@ -4,9 +4,15 @@ use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident};
|
||||
|
||||
use crate::event_parse::{to_kind_variation, EventKindVariation};
|
||||
|
||||
/// Derive `Event` macro code generation.
|
||||
pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
let ident = &input.ident;
|
||||
|
||||
let (_kind, var) = to_kind_variation(ident)
|
||||
.ok_or(syn::Error::new(Span::call_site(), "not a valid ruma event struct identifier"))?;
|
||||
|
||||
let (impl_gen, ty_gen, where_clause) = input.generics.split_for_impl();
|
||||
let is_generic = !input.generics.params.is_empty();
|
||||
|
||||
@ -37,7 +43,12 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let name = field.ident.as_ref().unwrap();
|
||||
if name == "content" && ident.to_string().contains("Redacted") {
|
||||
if name == "content" && matches!(
|
||||
var,
|
||||
EventKindVariation::Redacted
|
||||
| EventKindVariation::RedactedSync
|
||||
| EventKindVariation::RedactedStripped
|
||||
) {
|
||||
quote! {
|
||||
if ::ruma_events::RedactedEventContent::has_serialize_fields(&self.content) {
|
||||
state.serialize_field("content", &self.content)?;
|
||||
@ -92,7 +103,7 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
}
|
||||
};
|
||||
|
||||
let deserialize_impl = expand_deserialize_event(is_generic, input, fields)?;
|
||||
let deserialize_impl = expand_deserialize_event(input, &var, fields, is_generic)?;
|
||||
|
||||
Ok(quote! {
|
||||
#serialize_impl
|
||||
@ -102,9 +113,10 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
}
|
||||
|
||||
fn expand_deserialize_event(
|
||||
is_generic: bool,
|
||||
input: DeriveInput,
|
||||
var: &EventKindVariation,
|
||||
fields: Vec<Field>,
|
||||
is_generic: bool,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let ident = &input.ident;
|
||||
// we know there is a content field already
|
||||
@ -149,7 +161,12 @@ fn expand_deserialize_event(
|
||||
.map(|field| {
|
||||
let name = field.ident.as_ref().unwrap();
|
||||
if name == "content" {
|
||||
if is_generic && ident.to_string().contains("Redacted") {
|
||||
if is_generic && matches!(
|
||||
var,
|
||||
EventKindVariation::Redacted
|
||||
| EventKindVariation::RedactedSync
|
||||
| EventKindVariation::RedactedStripped
|
||||
) {
|
||||
quote! {
|
||||
let content = match C::has_deserialize_fields() {
|
||||
::ruma_events::HasDeserializeFields::False => {
|
||||
|
@ -22,6 +22,7 @@ pub enum EventKindVariation {
|
||||
Redacted,
|
||||
RedactedSync,
|
||||
RedactedStripped,
|
||||
ManuallyImpled,
|
||||
}
|
||||
|
||||
// If the variants of this enum change `to_event_path` needs to be updated as well.
|
||||
@ -31,6 +32,7 @@ pub enum EventKind {
|
||||
Message(Ident),
|
||||
State(Ident),
|
||||
ToDevice(Ident),
|
||||
ManuallyImpled(Ident),
|
||||
}
|
||||
|
||||
impl EventKind {
|
||||
@ -78,7 +80,8 @@ impl EventKind {
|
||||
| EventKind::Ephemeral(i)
|
||||
| EventKind::Message(i)
|
||||
| EventKind::State(i)
|
||||
| EventKind::ToDevice(i) => i,
|
||||
| EventKind::ToDevice(i)
|
||||
| EventKind::ManuallyImpled(i) => i,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,6 +108,44 @@ impl Parse for EventKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_kind_variation(ident: &Ident) -> Option<(EventKind, EventKindVariation)> {
|
||||
let ident_str = ident.to_string();
|
||||
match ident_str.as_str() {
|
||||
"BasicEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)),
|
||||
"EphemeralRoomEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)),
|
||||
"SyncEphemeralRoomEvent" => {
|
||||
Some((EventKind::Basic(ident.clone()), EventKindVariation::Sync))
|
||||
}
|
||||
"MessageEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)),
|
||||
"SyncMessageEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Sync)),
|
||||
"RedactedMessageEvent" => {
|
||||
Some((EventKind::Basic(ident.clone()), EventKindVariation::Redacted))
|
||||
}
|
||||
"RedactedSyncMessageEvent" => {
|
||||
Some((EventKind::Basic(ident.clone()), EventKindVariation::RedactedSync))
|
||||
}
|
||||
"StateEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)),
|
||||
"SyncStateEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Sync)),
|
||||
"StrippedStateEvent" => {
|
||||
Some((EventKind::Basic(ident.clone()), EventKindVariation::Stripped))
|
||||
}
|
||||
"RedactedStateEvent" => {
|
||||
Some((EventKind::Basic(ident.clone()), EventKindVariation::Redacted))
|
||||
}
|
||||
"RedactedSyncStateEvent" => {
|
||||
Some((EventKind::Basic(ident.clone()), EventKindVariation::RedactedSync))
|
||||
}
|
||||
"RedactedStrippedStateEvent" => {
|
||||
Some((EventKind::Basic(ident.clone()), EventKindVariation::RedactedStripped))
|
||||
}
|
||||
"ToDeviceEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)),
|
||||
"PresenceEvent" | "RedactionEvent" | "SyncRedactionEvent" => {
|
||||
Some((EventKind::ManuallyImpled(ident.clone()), EventKindVariation::ManuallyImpled))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// The entire `event_enum!` macro structure directly as it appears in the source code.
|
||||
pub struct EventEnumInput {
|
||||
/// Outer attributes on the field, such as a docstring.
|
||||
|
Loading…
x
Reference in New Issue
Block a user