Remove the Ident from EventKind and impl Display for both enums

This commit is contained in:
Devin R 2020-07-22 19:37:02 -04:00 committed by Jonas Platte
parent 2e1e63671d
commit 56ff7c05e9
2 changed files with 89 additions and 80 deletions

View File

@ -7,12 +7,12 @@ use syn::{Attribute, Ident, LitStr};
use crate::event_parse::{EventEnumInput, EventKind, EventKindVariation}; use crate::event_parse::{EventEnumInput, EventKind, EventKindVariation};
fn is_non_stripped_room_event(kind: &EventKind, var: &EventKindVariation) -> bool { fn is_non_stripped_room_event(kind: &EventKind, var: &EventKindVariation) -> bool {
matches!(kind, EventKind::Message(_) | EventKind::State(_)) matches!(kind, EventKind::Message | EventKind::State)
&& !matches!(var, EventKindVariation::Stripped | EventKindVariation::RedactedStripped) && !matches!(var, EventKindVariation::Stripped | EventKindVariation::RedactedStripped)
} }
fn has_prev_content_field(kind: &EventKind, var: &EventKindVariation) -> bool { fn has_prev_content_field(kind: &EventKind, var: &EventKindVariation) -> bool {
matches!(kind, EventKind::State(_)) matches!(kind, EventKind::State)
&& matches!(var, EventKindVariation::Full | EventKindVariation::Sync) && matches!(var, EventKindVariation::Full | EventKindVariation::Sync)
} }
@ -24,15 +24,14 @@ type EventKindFn = fn(&EventKind, &EventKindVariation) -> bool;
const EVENT_FIELDS: &[(&str, EventKindFn)] = &[ const EVENT_FIELDS: &[(&str, EventKindFn)] = &[
("origin_server_ts", is_non_stripped_room_event), ("origin_server_ts", is_non_stripped_room_event),
("room_id", |kind, var| { ("room_id", |kind, var| {
matches!(kind, EventKind::Message(_) | EventKind::State(_)) matches!(kind, EventKind::Message | EventKind::State)
&& matches!(var, EventKindVariation::Full | EventKindVariation::Redacted) && matches!(var, EventKindVariation::Full | EventKindVariation::Redacted)
}), }),
("event_id", is_non_stripped_room_event), ("event_id", is_non_stripped_room_event),
( ("sender", |kind, _| {
"sender", matches!(kind, EventKind::Message | EventKind::State | EventKind::ToDevice)
|kind, _| matches!(kind, EventKind::Message(_) | EventKind::State(_) | EventKind::ToDevice(_)), }),
), ("state_key", |kind, _| matches!(kind, EventKind::State)),
("state_key", |kind, _| matches!(kind, EventKind::State(_))),
("unsigned", is_non_stripped_room_event), ("unsigned", is_non_stripped_room_event),
]; ];
@ -319,7 +318,7 @@ fn expand_redact(
} }
fn expand_redacted_enum(kind: &EventKind, var: &EventKindVariation) -> Option<TokenStream> { fn expand_redacted_enum(kind: &EventKind, var: &EventKindVariation) -> Option<TokenStream> {
if let EventKind::State(_) | EventKind::Message(_) = kind { if let EventKind::State | EventKind::Message = kind {
let ident = format_ident!("AnyPossiblyRedacted{}", kind.to_event_ident(var)?); let ident = format_ident!("AnyPossiblyRedacted{}", kind.to_event_ident(var)?);
let (regular_enum_ident, redacted_enum_ident) = inner_enum_idents(kind, var)?; let (regular_enum_ident, redacted_enum_ident) = inner_enum_idents(kind, var)?;
@ -435,18 +434,18 @@ fn generate_custom_variant(
fn marker_traits(kind: &EventKind) -> TokenStream { fn marker_traits(kind: &EventKind) -> TokenStream {
let ident = kind.to_content_enum(); let ident = kind.to_content_enum();
match kind { match kind {
EventKind::State(_) => quote! { EventKind::State => quote! {
impl ::ruma_events::RoomEventContent for #ident {} impl ::ruma_events::RoomEventContent for #ident {}
impl ::ruma_events::StateEventContent for #ident {} impl ::ruma_events::StateEventContent for #ident {}
}, },
EventKind::Message(_) => quote! { EventKind::Message => quote! {
impl ::ruma_events::RoomEventContent for #ident {} impl ::ruma_events::RoomEventContent for #ident {}
impl ::ruma_events::MessageEventContent for #ident {} impl ::ruma_events::MessageEventContent for #ident {}
}, },
EventKind::Ephemeral(_) => quote! { EventKind::Ephemeral => quote! {
impl ::ruma_events::EphemeralRoomEventContent for #ident {} impl ::ruma_events::EphemeralRoomEventContent for #ident {}
}, },
EventKind::Basic(_) => quote! { EventKind::Basic => quote! {
impl ::ruma_events::BasicEventContent for #ident {} impl ::ruma_events::BasicEventContent for #ident {}
}, },
_ => TokenStream::new(), _ => TokenStream::new(),

View File

@ -1,6 +1,9 @@
//! Implementation of event enum and event content enum macros. //! Implementation of event enum and event content enum macros.
use std::fmt;
use matches::matches; use matches::matches;
use proc_macro2::Span;
use quote::format_ident; use quote::format_ident;
use syn::{ use syn::{
parse::{self, Parse, ParseStream}, parse::{self, Parse, ParseStream},
@ -22,7 +25,19 @@ pub enum EventKindVariation {
Redacted, Redacted,
RedactedSync, RedactedSync,
RedactedStripped, RedactedStripped,
ManuallyImpled, }
impl fmt::Display for EventKindVariation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EventKindVariation::Full => write!(f, ""),
EventKindVariation::Sync => write!(f, "Sync"),
EventKindVariation::Stripped => write!(f, "Stripped"),
EventKindVariation::Redacted => write!(f, "Redacted"),
EventKindVariation::RedactedSync => write!(f, "RedactedSync"),
EventKindVariation::RedactedStripped => write!(f, "RedactedStripped"),
}
}
} }
impl EventKindVariation { impl EventKindVariation {
@ -33,40 +48,55 @@ impl EventKindVariation {
// 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.
pub enum EventKind { pub enum EventKind {
Basic(Ident), Basic,
Ephemeral(Ident), Ephemeral,
Message(Ident), Message,
State(Ident), State,
ToDevice(Ident), ToDevice,
ManuallyImpled(Ident), Redaction,
Presence,
}
impl fmt::Display for EventKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EventKind::Basic => write!(f, "BasicEvent"),
EventKind::Ephemeral => write!(f, "EphemeralRoomEvent"),
EventKind::Message => write!(f, "MessageEvent"),
EventKind::State => write!(f, "StateEvent"),
EventKind::ToDevice => write!(f, "ToDeviceEvent"),
EventKind::Redaction => write!(f, "RedactionEvent"),
EventKind::Presence => write!(f, "PresenceEvent"),
}
}
} }
impl EventKind { impl EventKind {
pub fn is_state(&self) -> bool { pub fn is_state(&self) -> bool {
matches!(self, Self::State(_)) matches!(self, Self::State)
} }
pub fn is_message(&self) -> bool { pub fn is_message(&self) -> bool {
matches!(self, Self::Message(_)) matches!(self, Self::Message)
} }
pub fn to_event_ident(&self, var: &EventKindVariation) -> Option<Ident> { pub fn to_event_ident(&self, var: &EventKindVariation) -> Option<Ident> {
use EventKindVariation::*; use EventKindVariation::*;
// this match is only used to validate the input
match (self, var) { match (self, var) {
// all `EventKind`s are valid event structs and event enums. (_, Full)
(_, Full) => Some(format_ident!("{}Event", self.get_ident())), | (Self::Ephemeral, Sync)
(Self::Ephemeral(i), Sync) | (Self::Message(i), Sync) | (Self::State(i), Sync) => { | (Self::Message, Sync)
Some(format_ident!("Sync{}Event", i)) | (Self::State, Sync)
| (Self::State, Stripped)
| (Self::Message, Redacted)
| (Self::State, Redacted)
| (Self::Message, RedactedSync)
| (Self::State, RedactedSync)
| (Self::State, RedactedStripped) => {
Some(Ident::new(&format!("{}{}", var, self), Span::call_site()))
} }
(Self::State(i), Stripped) => Some(format_ident!("Stripped{}Event", i)),
(Self::Message(i), Redacted) | (Self::State(i), Redacted) => {
Some(format_ident!("Redacted{}Event", i))
}
(Self::Message(i), RedactedSync) | (Self::State(i), RedactedSync) => {
Some(format_ident!("RedactedSync{}Event", i))
}
(Self::State(i), RedactedStripped) => Some(format_ident!("RedactedStripped{}Event", i)),
_ => None, _ => None,
} }
} }
@ -77,18 +107,7 @@ impl EventKind {
/// `Any[kind]EventContent` /// `Any[kind]EventContent`
pub fn to_content_enum(&self) -> Ident { pub fn to_content_enum(&self) -> Ident {
format_ident!("Any{}EventContent", self.get_ident()) Ident::new(&format!("Any{}Content", self), Span::call_site())
}
pub fn get_ident(&self) -> &Ident {
match self {
EventKind::Basic(i)
| EventKind::Ephemeral(i)
| EventKind::Message(i)
| EventKind::State(i)
| EventKind::ToDevice(i)
| EventKind::ManuallyImpled(i) => i,
}
} }
} }
@ -96,11 +115,11 @@ impl Parse for EventKind {
fn parse(input: ParseStream) -> syn::Result<Self> { fn parse(input: ParseStream) -> syn::Result<Self> {
let ident = input.parse::<Ident>()?; let ident = input.parse::<Ident>()?;
Ok(match ident.to_string().as_str() { Ok(match ident.to_string().as_str() {
"Basic" => EventKind::Basic(ident), "Basic" => EventKind::Basic,
"EphemeralRoom" => EventKind::Ephemeral(ident), "EphemeralRoom" => EventKind::Ephemeral,
"Message" => EventKind::Message(ident), "Message" => EventKind::Message,
"State" => EventKind::State(ident), "State" => EventKind::State,
"ToDevice" => EventKind::ToDevice(ident), "ToDevice" => EventKind::ToDevice,
id => { id => {
return Err(syn::Error::new( return Err(syn::Error::new(
input.span(), input.span(),
@ -114,40 +133,31 @@ impl Parse for EventKind {
} }
} }
// This function is only used in the `Event` derive macro expansion code.
/// Validates the given `ident` is a valid event struct name and returns a tuple of enums
/// representing the name.
pub fn to_kind_variation(ident: &Ident) -> Option<(EventKind, EventKindVariation)> { pub fn to_kind_variation(ident: &Ident) -> Option<(EventKind, EventKindVariation)> {
let ident_str = ident.to_string(); let ident_str = ident.to_string();
match ident_str.as_str() { match ident_str.as_str() {
"BasicEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)), "BasicEvent" => Some((EventKind::Basic, EventKindVariation::Full)),
"EphemeralRoomEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)), "EphemeralRoomEvent" => Some((EventKind::Ephemeral, EventKindVariation::Full)),
"SyncEphemeralRoomEvent" => { "SyncEphemeralRoomEvent" => Some((EventKind::Ephemeral, EventKindVariation::Sync)),
Some((EventKind::Basic(ident.clone()), EventKindVariation::Sync)) "MessageEvent" => Some((EventKind::Message, EventKindVariation::Full)),
} "SyncMessageEvent" => Some((EventKind::Message, EventKindVariation::Sync)),
"MessageEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)), "RedactedMessageEvent" => Some((EventKind::Message, EventKindVariation::Redacted)),
"SyncMessageEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Sync)), "RedactedSyncMessageEvent" => Some((EventKind::Message, EventKindVariation::RedactedSync)),
"RedactedMessageEvent" => { "StateEvent" => Some((EventKind::State, EventKindVariation::Full)),
Some((EventKind::Basic(ident.clone()), EventKindVariation::Redacted)) "SyncStateEvent" => Some((EventKind::State, EventKindVariation::Sync)),
} "StrippedStateEvent" => Some((EventKind::State, EventKindVariation::Stripped)),
"RedactedSyncMessageEvent" => { "RedactedStateEvent" => Some((EventKind::State, EventKindVariation::Redacted)),
Some((EventKind::Basic(ident.clone()), EventKindVariation::RedactedSync)) "RedactedSyncStateEvent" => Some((EventKind::State, 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" => { "RedactedStrippedStateEvent" => {
Some((EventKind::Basic(ident.clone()), EventKindVariation::RedactedStripped)) Some((EventKind::State, EventKindVariation::RedactedStripped))
}
"ToDeviceEvent" => Some((EventKind::Basic(ident.clone()), EventKindVariation::Full)),
"PresenceEvent" | "RedactionEvent" | "SyncRedactionEvent" => {
Some((EventKind::ManuallyImpled(ident.clone()), EventKindVariation::ManuallyImpled))
} }
"ToDeviceEvent" => Some((EventKind::ToDevice, EventKindVariation::Full)),
"PresenceEvent" => Some((EventKind::Presence, EventKindVariation::Full)),
"RedactionEvent" => Some((EventKind::Redaction, EventKindVariation::Full)),
"SyncRedactionEvent" => Some((EventKind::Redaction, EventKindVariation::Sync)),
_ => None, _ => None,
} }
} }