macros: Require event module path for event_enum
This commit is contained in:
parent
82a4bb2e2b
commit
3ddc4de758
@ -15,108 +15,108 @@ use crate::{
|
||||
event_enum! {
|
||||
/// Any global account data event.
|
||||
enum GlobalAccountData {
|
||||
"m.direct",
|
||||
"m.identity_server",
|
||||
"m.ignored_user_list",
|
||||
"m.push_rules",
|
||||
"m.secret_storage.default_key",
|
||||
"m.secret_storage.key.*",
|
||||
"m.direct" => super::direct,
|
||||
"m.identity_server" => super::identity_server,
|
||||
"m.ignored_user_list" => super::ignored_user_list,
|
||||
"m.push_rules" => super::push_rules,
|
||||
"m.secret_storage.default_key" => super::secret_storage::default_key,
|
||||
"m.secret_storage.key.*" => super::secret_storage::key,
|
||||
}
|
||||
|
||||
/// Any room account data event.
|
||||
enum RoomAccountData {
|
||||
"m.fully_read",
|
||||
"m.tag",
|
||||
"m.fully_read" => super::fully_read,
|
||||
"m.tag" => super::tag,
|
||||
}
|
||||
|
||||
/// Any ephemeral room event.
|
||||
enum EphemeralRoom {
|
||||
"m.receipt",
|
||||
"m.typing",
|
||||
"m.receipt" => super::receipt,
|
||||
"m.typing" => super::typing,
|
||||
}
|
||||
|
||||
/// Any message-like event.
|
||||
enum MessageLike {
|
||||
#[cfg(feature = "unstable-msc3246")]
|
||||
"m.audio",
|
||||
"m.call.answer",
|
||||
"m.call.invite",
|
||||
"m.call.hangup",
|
||||
"m.call.candidates",
|
||||
"m.audio" => super::audio,
|
||||
"m.call.answer" => super::call::answer,
|
||||
"m.call.invite" => super::call::invite,
|
||||
"m.call.hangup" => super::call::hangup,
|
||||
"m.call.candidates" => super::call::candidates,
|
||||
#[cfg(feature = "unstable-msc1767")]
|
||||
"m.emote",
|
||||
"m.emote" => super::emote,
|
||||
#[cfg(feature = "unstable-msc3551")]
|
||||
"m.file",
|
||||
"m.file" => super::file,
|
||||
#[cfg(feature = "unstable-msc3552")]
|
||||
"m.image",
|
||||
"m.key.verification.ready",
|
||||
"m.key.verification.start",
|
||||
"m.key.verification.cancel",
|
||||
"m.key.verification.accept",
|
||||
"m.key.verification.key",
|
||||
"m.key.verification.mac",
|
||||
"m.key.verification.done",
|
||||
"m.image" => super::image,
|
||||
"m.key.verification.ready" => super::key::verification::ready,
|
||||
"m.key.verification.start" => super::key::verification::start,
|
||||
"m.key.verification.cancel" => super::key::verification::cancel,
|
||||
"m.key.verification.accept" => super::key::verification::accept,
|
||||
"m.key.verification.key" => super::key::verification::key,
|
||||
"m.key.verification.mac" => super::key::verification::mac,
|
||||
"m.key.verification.done" => super::key::verification::done,
|
||||
#[cfg(feature = "unstable-msc3488")]
|
||||
"m.location",
|
||||
"m.location" => super::location,
|
||||
#[cfg(feature = "unstable-msc1767")]
|
||||
"m.message",
|
||||
"m.message" => super::message,
|
||||
#[cfg(feature = "unstable-msc1767")]
|
||||
"m.notice",
|
||||
"m.notice" => super::notice,
|
||||
#[cfg(feature = "unstable-msc2677")]
|
||||
"m.reaction",
|
||||
"m.room.encrypted",
|
||||
"m.room.message",
|
||||
"m.room.message.feedback",
|
||||
"m.room.redaction",
|
||||
"m.sticker",
|
||||
"m.reaction" => super::reaction,
|
||||
"m.room.encrypted" => super::room::encrypted,
|
||||
"m.room.message" => super::room::message,
|
||||
"m.room.message.feedback" => super::room::message::feedback,
|
||||
"m.room.redaction" => super::room::redaction,
|
||||
"m.sticker" => super::sticker,
|
||||
#[cfg(feature = "unstable-msc3553")]
|
||||
"m.video",
|
||||
"m.video" => super::video,
|
||||
#[cfg(feature = "unstable-msc3245")]
|
||||
"m.voice",
|
||||
"m.voice" => super::voice,
|
||||
}
|
||||
|
||||
/// Any state event.
|
||||
enum State {
|
||||
"m.policy.rule.room",
|
||||
"m.policy.rule.server",
|
||||
"m.policy.rule.user",
|
||||
"m.room.aliases",
|
||||
"m.room.avatar",
|
||||
"m.room.canonical_alias",
|
||||
"m.room.create",
|
||||
"m.room.encryption",
|
||||
"m.room.guest_access",
|
||||
"m.room.history_visibility",
|
||||
"m.room.join_rules",
|
||||
"m.room.member",
|
||||
"m.room.name",
|
||||
"m.room.pinned_events",
|
||||
"m.room.power_levels",
|
||||
"m.room.server_acl",
|
||||
"m.room.third_party_invite",
|
||||
"m.room.tombstone",
|
||||
"m.room.topic",
|
||||
"m.space.child",
|
||||
"m.space.parent",
|
||||
"m.policy.rule.room" => super::policy::rule::room,
|
||||
"m.policy.rule.server" => super::policy::rule::server,
|
||||
"m.policy.rule.user" => super::policy::rule::user,
|
||||
"m.room.aliases" => super::room::aliases,
|
||||
"m.room.avatar" => super::room::avatar,
|
||||
"m.room.canonical_alias" => super::room::canonical_alias,
|
||||
"m.room.create" => super::room::create,
|
||||
"m.room.encryption" => super::room::encryption,
|
||||
"m.room.guest_access" => super::room::guest_access,
|
||||
"m.room.history_visibility" => super::room::history_visibility,
|
||||
"m.room.join_rules" => super::room::join_rules,
|
||||
"m.room.member" => super::room::member,
|
||||
"m.room.name" => super::room::name,
|
||||
"m.room.pinned_events" => super::room::pinned_events,
|
||||
"m.room.power_levels" => super::room::power_levels,
|
||||
"m.room.server_acl" => super::room::server_acl,
|
||||
"m.room.third_party_invite" => super::room::third_party_invite,
|
||||
"m.room.tombstone" => super::room::tombstone,
|
||||
"m.room.topic" => super::room::topic,
|
||||
"m.space.child" => super::space::child,
|
||||
"m.space.parent" => super::space::parent,
|
||||
}
|
||||
|
||||
/// Any to-device event.
|
||||
enum ToDevice {
|
||||
"m.dummy",
|
||||
"m.room_key",
|
||||
"m.room_key_request",
|
||||
"m.forwarded_room_key",
|
||||
"m.key.verification.request",
|
||||
"m.key.verification.ready",
|
||||
"m.key.verification.start",
|
||||
"m.key.verification.cancel",
|
||||
"m.key.verification.accept",
|
||||
"m.key.verification.key",
|
||||
"m.key.verification.mac",
|
||||
"m.key.verification.done",
|
||||
"m.room.encrypted",
|
||||
"m.secret.request",
|
||||
"m.secret.send",
|
||||
"m.dummy" => super::dummy,
|
||||
"m.room_key" => super::room_key,
|
||||
"m.room_key_request" => super::room_key_request,
|
||||
"m.forwarded_room_key" => super::forwarded_room_key,
|
||||
"m.key.verification.request" => super::key::verification::request,
|
||||
"m.key.verification.ready" => super::key::verification::ready,
|
||||
"m.key.verification.start" => super::key::verification::start,
|
||||
"m.key.verification.cancel" => super::key::verification::cancel,
|
||||
"m.key.verification.accept" => super::key::verification::accept,
|
||||
"m.key.verification.key" => super::key::verification::key,
|
||||
"m.key.verification.mac" => super::key::verification::mac,
|
||||
"m.key.verification.done" => super::key::verification::done,
|
||||
"m.room.encrypted" => super::room::encrypted,
|
||||
"m.secret.request"=> super::secret::request,
|
||||
"m.secret.send" => super::secret::send,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
use ruma_common::events;
|
||||
use ruma_macros::event_enum;
|
||||
|
||||
event_enum! {
|
||||
/// Any global account data event.
|
||||
enum GlobalAccountData {
|
||||
"m.direct",
|
||||
"m.direct" => events::direct,
|
||||
#[cfg(test)]
|
||||
"m.ignored_user_list",
|
||||
"m.ignored_user_list" => events::ignored_user_list,
|
||||
// Doesn't actually have a wildcard, but this should work as a wildcard test
|
||||
"m.push_rules.*",
|
||||
"m.push_rules.*" => events::push_rules,
|
||||
#[cfg(any())]
|
||||
"m.ruma_test",
|
||||
"m.ruma_test" => events::ruma_test,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
use ruma_common::events;
|
||||
use ruma_macros::event_enum;
|
||||
|
||||
event_enum! {
|
||||
enum State {
|
||||
"m.not.a.path",
|
||||
"m.not.a.path" => events::not::a::path,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0433]: failed to resolve: could not find `not` in `events`
|
||||
--> tests/events/ui/08-enum-invalid-path.rs:5:9
|
||||
--> tests/events/ui/08-enum-invalid-path.rs:6:35
|
||||
|
|
||||
5 | "m.not.a.path",
|
||||
| ^^^^^^^^^^^^^^ could not find `not` in `events`
|
||||
6 | "m.not.a.path" => events::not::a::path,
|
||||
| ^^^ could not find `not` in `events`
|
||||
|
@ -4,7 +4,7 @@ use std::fmt;
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, quote, IdentFragment, ToTokens};
|
||||
use syn::{Attribute, Data, DataEnum, DeriveInput, Ident, LitStr};
|
||||
use syn::{Attribute, Data, DataEnum, DeriveInput, Ident, LitStr, Path};
|
||||
|
||||
use super::event_parse::{EventEnumDecl, EventEnumEntry, EventKind};
|
||||
use crate::util::m_prefix_name_to_type_name;
|
||||
@ -49,7 +49,8 @@ pub fn expand_event_enums(input: &EventEnumDecl) -> syn::Result<TokenStream> {
|
||||
|
||||
let kind = input.kind;
|
||||
let attrs = &input.attrs;
|
||||
let events: Vec<_> = input.events.iter().map(|entry| entry.ev_type.clone()).collect();
|
||||
let events: Vec<_> =
|
||||
input.events.iter().map(|entry| (entry.ev_type.clone(), entry.ev_path.clone())).collect();
|
||||
let variants: Vec<_> =
|
||||
input.events.iter().map(EventEnumEntry::to_variant).collect::<syn::Result<_>>()?;
|
||||
|
||||
@ -110,7 +111,7 @@ pub fn expand_event_enums(input: &EventEnumDecl) -> syn::Result<TokenStream> {
|
||||
fn expand_event_enum(
|
||||
kind: EventKind,
|
||||
var: EventEnumVariation,
|
||||
events: &[LitStr],
|
||||
events: &[(LitStr, Path)],
|
||||
attrs: &[Attribute],
|
||||
variants: &[EventEnumVariant],
|
||||
ruma_common: &TokenStream,
|
||||
@ -120,7 +121,8 @@ fn expand_event_enum(
|
||||
|
||||
let variant_decls = variants.iter().map(|v| v.decl());
|
||||
let content: Vec<_> =
|
||||
events.iter().map(|event| to_event_path(event, kind, var, ruma_common)).collect();
|
||||
events.iter().map(|(name, path)| to_event_path(name, path, kind, var)).collect();
|
||||
let event_types: Vec<_> = events.iter().map(|(name, _)| name).collect();
|
||||
|
||||
let custom_ty = format_ident!("Custom{}Content", kind);
|
||||
|
||||
@ -131,11 +133,11 @@ fn expand_event_enum(
|
||||
Ok(quote! {
|
||||
#( #attrs )*
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[allow(clippy::large_enum_variant, unused_qualifications)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub enum #ident {
|
||||
#(
|
||||
#[doc = #events]
|
||||
#[doc = #event_types]
|
||||
#variant_decls(#content),
|
||||
)*
|
||||
/// An event not defined by the Matrix specification
|
||||
@ -154,7 +156,7 @@ fn expand_event_enum(
|
||||
fn expand_deserialize_impl(
|
||||
kind: EventKind,
|
||||
var: EventEnumVariation,
|
||||
events: &[LitStr],
|
||||
events: &[(LitStr, Path)],
|
||||
variants: &[EventEnumVariant],
|
||||
ruma_common: &TokenStream,
|
||||
) -> syn::Result<TokenStream> {
|
||||
@ -168,9 +170,11 @@ fn expand_deserialize_impl(
|
||||
quote! { #(#attrs)* }
|
||||
});
|
||||
let self_variants = variants.iter().map(|v| v.ctor(quote! { Self }));
|
||||
let content = events.iter().map(|event| to_event_path(event, kind, var, ruma_common));
|
||||
let content = events.iter().map(|(name, path)| to_event_path(name, path, kind, var));
|
||||
let event_types: Vec<_> = events.iter().map(|(name, _)| name).collect();
|
||||
|
||||
Ok(quote! {
|
||||
#[allow(unused_qualifications)]
|
||||
impl<'de> #serde::de::Deserialize<'de> for #ident {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
@ -184,7 +188,7 @@ fn expand_deserialize_impl(
|
||||
|
||||
match &*ev_type {
|
||||
#(
|
||||
#variant_attrs #events => {
|
||||
#variant_attrs #event_types => {
|
||||
let event = #serde_json::from_str::<#content>(json.get())
|
||||
.map_err(D::Error::custom)?;
|
||||
Ok(#self_variants(event))
|
||||
@ -210,6 +214,7 @@ fn expand_from_impl(
|
||||
let attrs = &variant.attrs;
|
||||
|
||||
quote! {
|
||||
#[allow(unused_qualifications)]
|
||||
#[automatically_derived]
|
||||
#(#attrs)*
|
||||
impl ::std::convert::From<#content> for #ty {
|
||||
@ -288,7 +293,7 @@ fn expand_into_full_event(
|
||||
/// Create a content enum from `EventEnumInput`.
|
||||
fn expand_content_enum(
|
||||
kind: EventKind,
|
||||
event_types: &[LitStr],
|
||||
events: &[(LitStr, Path)],
|
||||
attrs: &[Attribute],
|
||||
variants: &[EventEnumVariant],
|
||||
ruma_common: &TokenStream,
|
||||
@ -301,14 +306,15 @@ fn expand_content_enum(
|
||||
let event_type_enum = kind.to_event_type_enum();
|
||||
|
||||
let content: Vec<_> =
|
||||
event_types.iter().map(|ev| to_event_content_path(kind, ev, None, ruma_common)).collect();
|
||||
let event_type_match_arms = event_types.iter().map(|s| {
|
||||
events.iter().map(|(name, path)| to_event_content_path(kind, name, path, None)).collect();
|
||||
let event_type_match_arms = events.iter().map(|(s, _)| {
|
||||
if let Some(prefix) = s.value().strip_suffix(".*") {
|
||||
quote! { _s if _s.starts_with(#prefix) }
|
||||
} else {
|
||||
quote! { #s }
|
||||
}
|
||||
});
|
||||
let event_types: Vec<_> = events.iter().map(|(name, _)| name).collect();
|
||||
|
||||
let variant_decls = variants.iter().map(|v| v.decl()).collect::<Vec<_>>();
|
||||
let variant_attrs = variants.iter().map(|v| {
|
||||
@ -561,11 +567,10 @@ fn expand_accessor_methods(
|
||||
|
||||
fn to_event_path(
|
||||
name: &LitStr,
|
||||
path: &Path,
|
||||
kind: EventKind,
|
||||
var: EventEnumVariation,
|
||||
ruma_common: &TokenStream,
|
||||
) -> TokenStream {
|
||||
let path = event_module_path(name);
|
||||
let event = m_prefix_name_to_type_name(name).unwrap();
|
||||
let event_name = if kind == EventKind::ToDevice {
|
||||
assert_eq!(var, EventEnumVariation::None);
|
||||
@ -573,16 +578,15 @@ fn to_event_path(
|
||||
} else {
|
||||
format_ident!("{}{}Event", var, event)
|
||||
};
|
||||
quote! { #ruma_common::events::#( #path )::*::#event_name }
|
||||
quote! { #path::#event_name }
|
||||
}
|
||||
|
||||
fn to_event_content_path(
|
||||
kind: EventKind,
|
||||
name: &LitStr,
|
||||
path: &Path,
|
||||
prefix: Option<&str>,
|
||||
ruma_common: &TokenStream,
|
||||
) -> TokenStream {
|
||||
let path = event_module_path(name);
|
||||
let event = m_prefix_name_to_type_name(name).unwrap();
|
||||
let content_str = match kind {
|
||||
EventKind::ToDevice => {
|
||||
@ -592,21 +596,10 @@ fn to_event_content_path(
|
||||
};
|
||||
|
||||
quote! {
|
||||
#ruma_common::events::#( #path )::*::#content_str
|
||||
#path::#content_str
|
||||
}
|
||||
}
|
||||
|
||||
fn event_module_path(name: &LitStr) -> Vec<Ident> {
|
||||
let value = name.value();
|
||||
let value = value.strip_prefix("m.").unwrap();
|
||||
value
|
||||
.strip_suffix(".*")
|
||||
.unwrap_or(value)
|
||||
.split('.')
|
||||
.map(|s| Ident::new(s, name.span()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn field_return_type(name: &str, ruma_common: &TokenStream) -> TokenStream {
|
||||
match name {
|
||||
"origin_server_ts" => quote! { #ruma_common::MilliSecondsSinceUnixEpoch },
|
||||
|
@ -7,7 +7,7 @@ use quote::{format_ident, IdentFragment};
|
||||
use syn::{
|
||||
braced,
|
||||
parse::{self, Parse, ParseStream},
|
||||
Attribute, Ident, LitStr, Token,
|
||||
Attribute, Ident, LitStr, Path, Token,
|
||||
};
|
||||
|
||||
/// Custom keywords for the `event_enum!` macro
|
||||
@ -231,11 +231,17 @@ pub fn to_kind_variation(ident: &Ident) -> Option<(EventKind, EventKindVariation
|
||||
pub struct EventEnumEntry {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub ev_type: LitStr,
|
||||
pub ev_path: Path,
|
||||
}
|
||||
|
||||
impl Parse for EventEnumEntry {
|
||||
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
|
||||
Ok(Self { attrs: input.call(Attribute::parse_outer)?, ev_type: input.parse()? })
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
let ev_type: LitStr = input.parse()?;
|
||||
let _: Token![=>] = input.parse()?;
|
||||
let ev_path = input.call(Path::parse_mod_style)?;
|
||||
|
||||
Ok(Self { attrs, ev_type, ev_path })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{Ident, LitStr};
|
||||
use syn::{parse_quote, Ident, LitStr};
|
||||
|
||||
use super::event_parse::{EventEnumEntry, EventEnumInput, EventKind};
|
||||
|
||||
@ -38,6 +38,7 @@ pub fn expand_event_type_enum(
|
||||
let presence = vec![EventEnumEntry {
|
||||
attrs: vec![],
|
||||
ev_type: LitStr::new("m.presence", Span::call_site()),
|
||||
ev_path: parse_quote! { #ruma_common::events::presence },
|
||||
}];
|
||||
let mut all = input.enums.iter().map(|e| &e.events).collect::<Vec<_>>();
|
||||
all.push(&presence);
|
||||
|
Loading…
x
Reference in New Issue
Block a user