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 quote::quote;
|
||||||
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident};
|
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident};
|
||||||
|
|
||||||
|
use crate::event_parse::{to_kind_variation, EventKindVariation};
|
||||||
|
|
||||||
/// Derive `Event` macro code generation.
|
/// Derive `Event` macro code generation.
|
||||||
pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||||
let ident = &input.ident;
|
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 (impl_gen, ty_gen, where_clause) = input.generics.split_for_impl();
|
||||||
let is_generic = !input.generics.params.is_empty();
|
let is_generic = !input.generics.params.is_empty();
|
||||||
|
|
||||||
@ -37,7 +43,12 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let name = field.ident.as_ref().unwrap();
|
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! {
|
quote! {
|
||||||
if ::ruma_events::RedactedEventContent::has_serialize_fields(&self.content) {
|
if ::ruma_events::RedactedEventContent::has_serialize_fields(&self.content) {
|
||||||
state.serialize_field("content", &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! {
|
Ok(quote! {
|
||||||
#serialize_impl
|
#serialize_impl
|
||||||
@ -102,9 +113,10 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expand_deserialize_event(
|
fn expand_deserialize_event(
|
||||||
is_generic: bool,
|
|
||||||
input: DeriveInput,
|
input: DeriveInput,
|
||||||
|
var: &EventKindVariation,
|
||||||
fields: Vec<Field>,
|
fields: Vec<Field>,
|
||||||
|
is_generic: bool,
|
||||||
) -> syn::Result<TokenStream> {
|
) -> syn::Result<TokenStream> {
|
||||||
let ident = &input.ident;
|
let ident = &input.ident;
|
||||||
// we know there is a content field already
|
// we know there is a content field already
|
||||||
@ -149,7 +161,12 @@ fn expand_deserialize_event(
|
|||||||
.map(|field| {
|
.map(|field| {
|
||||||
let name = field.ident.as_ref().unwrap();
|
let name = field.ident.as_ref().unwrap();
|
||||||
if name == "content" {
|
if name == "content" {
|
||||||
if is_generic && ident.to_string().contains("Redacted") {
|
if is_generic && matches!(
|
||||||
|
var,
|
||||||
|
EventKindVariation::Redacted
|
||||||
|
| EventKindVariation::RedactedSync
|
||||||
|
| EventKindVariation::RedactedStripped
|
||||||
|
) {
|
||||||
quote! {
|
quote! {
|
||||||
let content = match C::has_deserialize_fields() {
|
let content = match C::has_deserialize_fields() {
|
||||||
::ruma_events::HasDeserializeFields::False => {
|
::ruma_events::HasDeserializeFields::False => {
|
||||||
|
@ -22,6 +22,7 @@ pub enum EventKindVariation {
|
|||||||
Redacted,
|
Redacted,
|
||||||
RedactedSync,
|
RedactedSync,
|
||||||
RedactedStripped,
|
RedactedStripped,
|
||||||
|
ManuallyImpled,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the variants of this enum change `to_event_path` needs to be updated as well.
|
// 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),
|
Message(Ident),
|
||||||
State(Ident),
|
State(Ident),
|
||||||
ToDevice(Ident),
|
ToDevice(Ident),
|
||||||
|
ManuallyImpled(Ident),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventKind {
|
impl EventKind {
|
||||||
@ -78,7 +80,8 @@ impl EventKind {
|
|||||||
| EventKind::Ephemeral(i)
|
| EventKind::Ephemeral(i)
|
||||||
| EventKind::Message(i)
|
| EventKind::Message(i)
|
||||||
| EventKind::State(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.
|
/// The entire `event_enum!` macro structure directly as it appears in the source code.
|
||||||
pub struct EventEnumInput {
|
pub struct EventEnumInput {
|
||||||
/// Outer attributes on the field, such as a docstring.
|
/// Outer attributes on the field, such as a docstring.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user