events: Declare all event enums inside one macro invocation
This commit is contained in:
parent
a4811663de
commit
d1f5fb1d87
@ -4,7 +4,7 @@ use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use syn::{Attribute, Ident, LitStr};
|
||||
|
||||
use crate::event_parse::{EventEnumEntry, EventEnumInput, EventKind, EventKindVariation};
|
||||
use crate::event_parse::{EventEnumDecl, EventEnumEntry, EventKind, EventKindVariation};
|
||||
|
||||
fn is_non_stripped_room_event(kind: &EventKind, var: &EventKindVariation) -> bool {
|
||||
matches!(kind, EventKind::Message | EventKind::State)
|
||||
@ -43,7 +43,7 @@ const EVENT_FIELDS: &[(&str, EventKindFn)] = &[
|
||||
];
|
||||
|
||||
/// Create a content enum from `EventEnumInput`.
|
||||
pub fn expand_event_enum(input: EventEnumInput) -> syn::Result<TokenStream> {
|
||||
pub fn expand_event_enum(input: &EventEnumDecl) -> syn::Result<TokenStream> {
|
||||
let ruma_events = crate::import_ruma_events();
|
||||
|
||||
let name = &input.name;
|
||||
@ -969,13 +969,13 @@ fn field_return_type(
|
||||
}
|
||||
}
|
||||
|
||||
struct EventEnumVariant {
|
||||
pub(crate) struct EventEnumVariant {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub ident: Ident,
|
||||
}
|
||||
|
||||
impl EventEnumVariant {
|
||||
fn to_tokens<T>(&self, prefix: Option<T>, with_attrs: bool) -> TokenStream
|
||||
pub(crate) fn to_tokens<T>(&self, prefix: Option<T>, with_attrs: bool) -> TokenStream
|
||||
where
|
||||
T: ToTokens,
|
||||
{
|
||||
@ -993,21 +993,21 @@ impl EventEnumVariant {
|
||||
tokens
|
||||
}
|
||||
|
||||
fn decl(&self) -> TokenStream {
|
||||
pub(crate) fn decl(&self) -> TokenStream {
|
||||
self.to_tokens::<TokenStream>(None, true)
|
||||
}
|
||||
|
||||
fn match_arm(&self, prefix: impl ToTokens) -> TokenStream {
|
||||
pub(crate) fn match_arm(&self, prefix: impl ToTokens) -> TokenStream {
|
||||
self.to_tokens(Some(prefix), true)
|
||||
}
|
||||
|
||||
fn ctor(&self, prefix: impl ToTokens) -> TokenStream {
|
||||
pub(crate) fn ctor(&self, prefix: impl ToTokens) -> TokenStream {
|
||||
self.to_tokens(Some(prefix), false)
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEnumEntry {
|
||||
fn to_variant(&self) -> syn::Result<EventEnumVariant> {
|
||||
pub(crate) fn to_variant(&self) -> syn::Result<EventEnumVariant> {
|
||||
let attrs = self.attrs.clone();
|
||||
let ident = to_camel_case(&self.ev_type)?;
|
||||
Ok(EventEnumVariant { attrs, ident })
|
||||
|
@ -5,7 +5,7 @@ use std::fmt;
|
||||
use proc_macro2::Span;
|
||||
use quote::format_ident;
|
||||
use syn::{
|
||||
bracketed,
|
||||
braced,
|
||||
parse::{self, Parse, ParseStream},
|
||||
Attribute, Ident, LitStr, Token,
|
||||
};
|
||||
@ -140,8 +140,8 @@ impl Parse for EventKind {
|
||||
"State" => EventKind::State,
|
||||
"ToDevice" => EventKind::ToDevice,
|
||||
id => {
|
||||
return Err(syn::Error::new(
|
||||
input.span(),
|
||||
return Err(syn::Error::new_spanned(
|
||||
ident,
|
||||
format!(
|
||||
"valid event kinds are GlobalAccountData, RoomAccountData, EphemeralRoom, \
|
||||
Message, State, ToDevice found `{}`",
|
||||
@ -184,48 +184,6 @@ pub fn to_kind_variation(ident: &Ident) -> Option<(EventKind, EventKindVariation
|
||||
}
|
||||
}
|
||||
|
||||
/// 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.
|
||||
pub attrs: Vec<Attribute>,
|
||||
|
||||
/// The name of the event.
|
||||
pub name: EventKind,
|
||||
|
||||
/// An array of valid matrix event types.
|
||||
///
|
||||
/// This will generate the variants of the event type "name". There needs to be a corresponding
|
||||
/// variant in `ruma_events::EventType` for this event (converted to a valid Rust-style type
|
||||
/// name by stripping `m.`, replacing the remaining dots by underscores and then converting
|
||||
/// from snake_case to CamelCase).
|
||||
pub events: Vec<EventEnumEntry>,
|
||||
}
|
||||
|
||||
impl Parse for EventEnumInput {
|
||||
fn parse(input: ParseStream<'_>) -> parse::Result<Self> {
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
// "name" field
|
||||
let _: kw::kind = input.parse()?;
|
||||
let _: Token![:] = input.parse()?;
|
||||
|
||||
// the name of our event enum
|
||||
let name: EventKind = input.parse()?;
|
||||
let _: Token![,] = input.parse()?;
|
||||
|
||||
// "events" field
|
||||
let _: kw::events = input.parse()?;
|
||||
let _: Token![:] = input.parse()?;
|
||||
|
||||
// an array of event names `["m.room.whatever", ...]`
|
||||
let content;
|
||||
bracketed!(content in input);
|
||||
let events = content.parse_terminated::<_, Token![,]>(EventEnumEntry::parse)?;
|
||||
let events = events.into_iter().collect();
|
||||
|
||||
Ok(Self { attrs, name, events })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventEnumEntry {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub ev_type: LitStr,
|
||||
@ -236,3 +194,44 @@ impl Parse for EventEnumEntry {
|
||||
Ok(Self { attrs: input.call(Attribute::parse_outer)?, ev_type: input.parse()? })
|
||||
}
|
||||
}
|
||||
|
||||
/// The entire `event_enum!` macro structure directly as it appears in the source code.
|
||||
pub struct EventEnumDecl {
|
||||
/// Outer attributes on the field, such as a docstring.
|
||||
pub attrs: Vec<Attribute>,
|
||||
|
||||
/// The name of the event.
|
||||
pub name: EventKind,
|
||||
|
||||
/// An array of valid matrix event types.
|
||||
///
|
||||
/// This will generate the variants of the event type "kind". There needs to be a corresponding
|
||||
/// variant in `ruma_events::EventType` for this event (converted to a valid Rust-style type
|
||||
/// name by stripping `m.`, replacing the remaining dots by underscores and then converting
|
||||
/// from snake_case to CamelCase).
|
||||
pub events: Vec<EventEnumEntry>,
|
||||
}
|
||||
|
||||
/// The entire `event_enum!` macro structure directly as it appears in the source code.
|
||||
pub struct EventEnumInput {
|
||||
pub(crate) enums: Vec<EventEnumDecl>,
|
||||
}
|
||||
|
||||
impl Parse for EventEnumInput {
|
||||
fn parse(input: ParseStream<'_>) -> parse::Result<Self> {
|
||||
let mut enums = vec![];
|
||||
while !input.is_empty() {
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
|
||||
let _: Token![enum] = input.parse()?;
|
||||
let name: EventKind = input.parse()?;
|
||||
|
||||
let content;
|
||||
braced!(content in input);
|
||||
let events = content.parse_terminated::<_, Token![,]>(EventEnumEntry::parse)?;
|
||||
let events = events.into_iter().collect();
|
||||
enums.push(EventEnumDecl { attrs, name, events });
|
||||
}
|
||||
Ok(EventEnumInput { enums })
|
||||
}
|
||||
}
|
||||
|
176
crates/ruma-events-macros/src/event_type.rs
Normal file
176
crates/ruma-events-macros/src/event_type.rs
Normal file
@ -0,0 +1,176 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{Ident, LitStr};
|
||||
|
||||
use crate::event_parse::{EventEnumEntry, EventEnumInput, EventKind};
|
||||
|
||||
pub fn expand_event_type_enum(
|
||||
input: EventEnumInput,
|
||||
ruma_events: TokenStream,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let ruma_serde = quote! { #ruma_events::exports::ruma_serde };
|
||||
|
||||
let mut room: Vec<&Vec<EventEnumEntry>> = vec![];
|
||||
let mut state: Vec<&Vec<EventEnumEntry>> = vec![];
|
||||
let mut message: Vec<&Vec<EventEnumEntry>> = vec![];
|
||||
let mut ephemeral: Vec<&Vec<EventEnumEntry>> = vec![];
|
||||
let mut room_account: Vec<&Vec<EventEnumEntry>> = vec![];
|
||||
let mut global_account: Vec<&Vec<EventEnumEntry>> = vec![];
|
||||
let mut to_device: Vec<&Vec<EventEnumEntry>> = vec![];
|
||||
for event in &input.enums {
|
||||
match event.name {
|
||||
EventKind::GlobalAccountData => global_account.push(&event.events),
|
||||
EventKind::RoomAccountData => room_account.push(&event.events),
|
||||
EventKind::Ephemeral => ephemeral.push(&event.events),
|
||||
EventKind::Message => {
|
||||
message.push(&event.events);
|
||||
room.push(&event.events);
|
||||
}
|
||||
EventKind::State => {
|
||||
state.push(&event.events);
|
||||
room.push(&event.events);
|
||||
}
|
||||
EventKind::ToDevice => to_device.push(&event.events),
|
||||
EventKind::Redaction => {}
|
||||
EventKind::Presence => {}
|
||||
}
|
||||
}
|
||||
let presence = vec![EventEnumEntry {
|
||||
attrs: vec![],
|
||||
ev_type: LitStr::new("m.presence", Span::call_site()),
|
||||
}];
|
||||
let mut all = input.enums.iter().map(|e| &e.events).collect::<Vec<_>>();
|
||||
all.push(&presence);
|
||||
let (all_event_types, all_str_ev_types) = generate_variants(&all)?;
|
||||
let all =
|
||||
generate_enum(format_ident!("EventType"), all_str_ev_types, all_event_types, &ruma_serde);
|
||||
|
||||
let (room_event_types, room_str_ev_types) = generate_variants(&room)?;
|
||||
let room = generate_enum(
|
||||
format_ident!("RoomEventType"),
|
||||
room_str_ev_types,
|
||||
room_event_types,
|
||||
&ruma_serde,
|
||||
);
|
||||
|
||||
let (state_event_types, state_str_ev_types) = generate_variants(&state)?;
|
||||
let state = generate_enum(
|
||||
format_ident!("StateEventType"),
|
||||
state_str_ev_types,
|
||||
state_event_types,
|
||||
&ruma_serde,
|
||||
);
|
||||
|
||||
let (message_event_types, message_str_ev_types) = generate_variants(&message)?;
|
||||
let message = generate_enum(
|
||||
format_ident!("MessageEventType"),
|
||||
message_str_ev_types,
|
||||
message_event_types,
|
||||
&ruma_serde,
|
||||
);
|
||||
|
||||
let (ephemeral_event_types, ephemeral_str_ev_types) = generate_variants(&ephemeral)?;
|
||||
let ephemeral = generate_enum(
|
||||
format_ident!("EphemeralRoomEventType"),
|
||||
ephemeral_str_ev_types,
|
||||
ephemeral_event_types,
|
||||
&ruma_serde,
|
||||
);
|
||||
|
||||
let (room_account_event_types, room_account_str_ev_types) = generate_variants(&room_account)?;
|
||||
let room_account = generate_enum(
|
||||
format_ident!("RoomAccountDataEventType"),
|
||||
room_account_str_ev_types,
|
||||
room_account_event_types,
|
||||
&ruma_serde,
|
||||
);
|
||||
|
||||
let (global_account_event_types, global_account_str_ev_types) =
|
||||
generate_variants(&global_account)?;
|
||||
let global_account = generate_enum(
|
||||
format_ident!("GlobalAccountDataEventType"),
|
||||
global_account_str_ev_types,
|
||||
global_account_event_types,
|
||||
&ruma_serde,
|
||||
);
|
||||
|
||||
let (to_device_event_types, to_device_str_ev_types) = generate_variants(&to_device)?;
|
||||
let to_device = generate_enum(
|
||||
format_ident!("ToDeviceEventType"),
|
||||
to_device_str_ev_types,
|
||||
to_device_event_types,
|
||||
&ruma_serde,
|
||||
);
|
||||
|
||||
Ok(quote! {
|
||||
#all
|
||||
#room
|
||||
#state
|
||||
#message
|
||||
#ephemeral
|
||||
#room_account
|
||||
#global_account
|
||||
#to_device
|
||||
})
|
||||
}
|
||||
|
||||
fn generate_enum(
|
||||
ident: Ident,
|
||||
ev_type_strings: Vec<&LitStr>,
|
||||
variants: Vec<TokenStream>,
|
||||
ruma_serde: &TokenStream,
|
||||
) -> TokenStream {
|
||||
let str_doc = format!("Creates a string slice from this `{}`.", ident);
|
||||
let byte_doc = format!("Creates a byte slice from this `{}`.", ident);
|
||||
let enum_doc = format!("The type of `{}` this is.", ident);
|
||||
quote! {
|
||||
#[doc = #enum_doc]
|
||||
///
|
||||
/// This type can hold an arbitrary string. To check for events that are not available as a
|
||||
/// documented variant here, use its string representation, obtained through `.as_str()`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, #ruma_serde::StringEnum)]
|
||||
pub enum #ident {
|
||||
#(
|
||||
#[doc = #ev_type_strings]
|
||||
#[ruma_enum(rename = #ev_type_strings)]
|
||||
#variants,
|
||||
)*
|
||||
#[doc(hidden)]
|
||||
_Custom(String),
|
||||
}
|
||||
|
||||
impl #ident {
|
||||
#[doc = #str_doc]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.as_ref()
|
||||
}
|
||||
|
||||
#[doc = #byte_doc]
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
self.as_str().as_bytes()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_variants<'a>(
|
||||
input: &'a [&Vec<EventEnumEntry>],
|
||||
) -> syn::Result<(Vec<TokenStream>, Vec<&'a LitStr>)> {
|
||||
let mut deduped: Vec<&EventEnumEntry> = vec![];
|
||||
for item in input.iter().copied().flatten() {
|
||||
if let Some(idx) = deduped.iter().position(|e| e.ev_type == item.ev_type) {
|
||||
// If there is a variant without config attributes use that
|
||||
if deduped[idx].attrs != item.attrs && item.attrs.is_empty() {
|
||||
deduped[idx] = item;
|
||||
}
|
||||
} else {
|
||||
deduped.push(item);
|
||||
}
|
||||
}
|
||||
let event_types = deduped.iter().map(|e| &e.ev_type).collect();
|
||||
|
||||
let event_types_variants =
|
||||
deduped.iter().map(|e| Ok(e.to_variant()?.decl())).collect::<syn::Result<Vec<_>>>()?;
|
||||
|
||||
Ok((event_types_variants, event_types))
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use event_parse::EventEnumInput;
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2 as pm2;
|
||||
use proc_macro_crate::{crate_name, FoundCrate};
|
||||
@ -16,13 +17,15 @@ use syn::{parse_macro_input, DeriveInput, Ident};
|
||||
|
||||
use self::{
|
||||
event::expand_event, event_content::expand_event_content, event_enum::expand_event_enum,
|
||||
event_parse::EventEnumInput,
|
||||
event_type::expand_event_type_enum,
|
||||
};
|
||||
|
||||
mod event;
|
||||
mod event_content;
|
||||
mod event_enum;
|
||||
mod event_parse;
|
||||
mod event_type;
|
||||
|
||||
/// Generates an enum to represent the various Matrix event types.
|
||||
///
|
||||
/// This macro also implements the necessary traits for the type to serialize and deserialize
|
||||
@ -35,20 +38,40 @@ mod event_parse;
|
||||
/// use ruma_events_macros::event_enum;
|
||||
///
|
||||
/// event_enum! {
|
||||
/// kind: ToDevice,
|
||||
/// events: [
|
||||
/// enum ToDevice {
|
||||
/// "m.any.event",
|
||||
/// "m.other.event",
|
||||
/// ]
|
||||
/// }
|
||||
///
|
||||
/// enum State {
|
||||
/// "m.more.events",
|
||||
/// "m.different.event",
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// (The argument to `kind` has to be a valid identifier for `<EventKind as Parse>::parse`)
|
||||
/// (The enum name has to be a valid identifier for `<EventKind as Parse>::parse`)
|
||||
//// TODO: Change above (`<EventKind as Parse>::parse`) to [] after fully qualified syntax is
|
||||
//// supported: https://github.com/rust-lang/rust/issues/74563
|
||||
#[proc_macro]
|
||||
pub fn event_enum(input: TokenStream) -> TokenStream {
|
||||
let ruma_events = import_ruma_events();
|
||||
|
||||
let event_enum_input = syn::parse_macro_input!(input as EventEnumInput);
|
||||
expand_event_enum(event_enum_input).unwrap_or_else(syn::Error::into_compile_error).into()
|
||||
let enums = event_enum_input
|
||||
.enums
|
||||
.iter()
|
||||
.map(expand_event_enum)
|
||||
.collect::<syn::Result<pm2::TokenStream>>();
|
||||
let event_types = expand_event_type_enum(event_enum_input, ruma_events);
|
||||
event_types
|
||||
.and_then(|types| {
|
||||
enums.map(|mut enums| {
|
||||
enums.extend(types);
|
||||
enums
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Generates an implementation of `ruma_events::EventContent`.
|
||||
|
@ -6,36 +6,26 @@ use crate::{from_raw_json_value, EventDeHelper};
|
||||
|
||||
event_enum! {
|
||||
/// Any global account data event.
|
||||
kind: GlobalAccountData,
|
||||
events: [
|
||||
enum GlobalAccountData {
|
||||
"m.direct",
|
||||
"m.ignored_user_list",
|
||||
"m.push_rules",
|
||||
]
|
||||
}
|
||||
|
||||
event_enum! {
|
||||
/// Any room account data event.
|
||||
kind: RoomAccountData,
|
||||
events: [
|
||||
enum RoomAccountData {
|
||||
"m.fully_read",
|
||||
"m.tag",
|
||||
]
|
||||
}
|
||||
|
||||
event_enum! {
|
||||
/// Any ephemeral room event.
|
||||
kind: EphemeralRoom,
|
||||
events: [
|
||||
enum EphemeralRoom {
|
||||
"m.receipt",
|
||||
"m.typing",
|
||||
]
|
||||
}
|
||||
|
||||
event_enum! {
|
||||
/// Any message event.
|
||||
kind: Message,
|
||||
events: [
|
||||
enum Message {
|
||||
"m.call.answer",
|
||||
"m.call.invite",
|
||||
"m.call.hangup",
|
||||
@ -69,13 +59,11 @@ event_enum! {
|
||||
"m.room.message.feedback",
|
||||
"m.room.redaction",
|
||||
"m.sticker",
|
||||
]
|
||||
}
|
||||
|
||||
event_enum! {
|
||||
|
||||
/// Any state event.
|
||||
kind: State,
|
||||
events: [
|
||||
enum State {
|
||||
"m.policy.rule.room",
|
||||
"m.policy.rule.server",
|
||||
"m.policy.rule.user",
|
||||
@ -95,13 +83,10 @@ event_enum! {
|
||||
"m.room.third_party_invite",
|
||||
"m.room.tombstone",
|
||||
"m.room.topic",
|
||||
]
|
||||
}
|
||||
|
||||
event_enum! {
|
||||
/// Any to-device event.
|
||||
kind: ToDevice,
|
||||
events: [
|
||||
enum ToDevice {
|
||||
"m.dummy",
|
||||
"m.room_key",
|
||||
"m.room_key_request",
|
||||
@ -119,7 +104,7 @@ event_enum! {
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "unstable-pre-spec")))]
|
||||
"m.key.verification.done",
|
||||
"m.room.encrypted",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/// Any room event.
|
||||
|
@ -1,278 +0,0 @@
|
||||
use ruma_serde::StringEnum;
|
||||
|
||||
/// The type of an event.
|
||||
///
|
||||
/// This type can hold an arbitrary string. To check for events that are not available as a
|
||||
/// documented variant here, use its string representation, obtained through `.as_str()`.
|
||||
// FIXME: Add `m.foo.bar` or `m.foo_bar` as a naming scheme in StringEnum and remove most rename
|
||||
// attributes.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, StringEnum)]
|
||||
pub enum EventType {
|
||||
/// m.call.answer
|
||||
#[ruma_enum(rename = "m.call.answer")]
|
||||
CallAnswer,
|
||||
|
||||
/// m.call.candidates
|
||||
#[ruma_enum(rename = "m.call.candidates")]
|
||||
CallCandidates,
|
||||
|
||||
/// m.call.hangup
|
||||
#[ruma_enum(rename = "m.call.hangup")]
|
||||
CallHangup,
|
||||
|
||||
/// m.call.invite
|
||||
#[ruma_enum(rename = "m.call.invite")]
|
||||
CallInvite,
|
||||
|
||||
/// m.direct
|
||||
#[ruma_enum(rename = "m.direct")]
|
||||
Direct,
|
||||
|
||||
/// m.dummy
|
||||
#[ruma_enum(rename = "m.dummy")]
|
||||
Dummy,
|
||||
|
||||
/// m.forwarded_room_key
|
||||
#[ruma_enum(rename = "m.forwarded_room_key")]
|
||||
ForwardedRoomKey,
|
||||
|
||||
/// m.fully_read
|
||||
#[ruma_enum(rename = "m.fully_read")]
|
||||
FullyRead,
|
||||
|
||||
/// m.key.verification.accept
|
||||
#[ruma_enum(rename = "m.key.verification.accept")]
|
||||
KeyVerificationAccept,
|
||||
|
||||
/// m.key.verification.cancel
|
||||
#[ruma_enum(rename = "m.key.verification.cancel")]
|
||||
KeyVerificationCancel,
|
||||
|
||||
/// m.key.verification.done
|
||||
#[ruma_enum(rename = "m.key.verification.done")]
|
||||
KeyVerificationDone,
|
||||
|
||||
/// m.key.verification.key
|
||||
#[ruma_enum(rename = "m.key.verification.key")]
|
||||
KeyVerificationKey,
|
||||
|
||||
/// m.key.verification.mac
|
||||
#[ruma_enum(rename = "m.key.verification.mac")]
|
||||
KeyVerificationMac,
|
||||
|
||||
/// m.key.verification.ready
|
||||
#[ruma_enum(rename = "m.key.verification.ready")]
|
||||
KeyVerificationReady,
|
||||
|
||||
/// m.key.verification.request
|
||||
#[ruma_enum(rename = "m.key.verification.request")]
|
||||
KeyVerificationRequest,
|
||||
|
||||
/// m.key.verification.start
|
||||
#[ruma_enum(rename = "m.key.verification.start")]
|
||||
KeyVerificationStart,
|
||||
|
||||
/// m.ignored_user_list
|
||||
#[ruma_enum(rename = "m.ignored_user_list")]
|
||||
IgnoredUserList,
|
||||
|
||||
/// m.policy.rule.room
|
||||
#[ruma_enum(rename = "m.policy.rule.room")]
|
||||
PolicyRuleRoom,
|
||||
|
||||
/// m.policy.rule.server
|
||||
#[ruma_enum(rename = "m.policy.rule.server")]
|
||||
PolicyRuleServer,
|
||||
|
||||
/// m.policy.rule.user
|
||||
#[ruma_enum(rename = "m.policy.rule.user")]
|
||||
PolicyRuleUser,
|
||||
|
||||
/// m.presence
|
||||
#[ruma_enum(rename = "m.presence")]
|
||||
Presence,
|
||||
|
||||
/// m.push_rules
|
||||
#[ruma_enum(rename = "m.push_rules")]
|
||||
PushRules,
|
||||
|
||||
/// m.receipt
|
||||
#[ruma_enum(rename = "m.receipt")]
|
||||
Receipt,
|
||||
|
||||
/// m.room.aliases
|
||||
#[ruma_enum(rename = "m.room.aliases")]
|
||||
RoomAliases,
|
||||
|
||||
/// m.room.avatar
|
||||
#[ruma_enum(rename = "m.room.avatar")]
|
||||
RoomAvatar,
|
||||
|
||||
/// m.room.canonical_alias
|
||||
#[ruma_enum(rename = "m.room.canonical_alias")]
|
||||
RoomCanonicalAlias,
|
||||
|
||||
/// m.room.create
|
||||
#[ruma_enum(rename = "m.room.create")]
|
||||
RoomCreate,
|
||||
|
||||
/// m.room.encrypted
|
||||
#[ruma_enum(rename = "m.room.encrypted")]
|
||||
RoomEncrypted,
|
||||
|
||||
/// m.room.encryption
|
||||
#[ruma_enum(rename = "m.room.encryption")]
|
||||
RoomEncryption,
|
||||
|
||||
/// m.room.guest_access
|
||||
#[ruma_enum(rename = "m.room.guest_access")]
|
||||
RoomGuestAccess,
|
||||
|
||||
/// m.room.history_visibility
|
||||
#[ruma_enum(rename = "m.room.history_visibility")]
|
||||
RoomHistoryVisibility,
|
||||
|
||||
/// m.room.join_rules
|
||||
#[ruma_enum(rename = "m.room.join_rules")]
|
||||
RoomJoinRules,
|
||||
|
||||
/// m.room.member
|
||||
#[ruma_enum(rename = "m.room.member")]
|
||||
RoomMember,
|
||||
|
||||
/// m.room.message
|
||||
#[ruma_enum(rename = "m.room.message")]
|
||||
RoomMessage,
|
||||
|
||||
/// m.room.message.feedback
|
||||
#[ruma_enum(rename = "m.room.message.feedback")]
|
||||
RoomMessageFeedback,
|
||||
|
||||
/// m.room.name
|
||||
#[ruma_enum(rename = "m.room.name")]
|
||||
RoomName,
|
||||
|
||||
/// m.room.pinned_events
|
||||
#[ruma_enum(rename = "m.room.pinned_events")]
|
||||
RoomPinnedEvents,
|
||||
|
||||
/// m.room.power_levels
|
||||
#[ruma_enum(rename = "m.room.power_levels")]
|
||||
RoomPowerLevels,
|
||||
|
||||
/// m.room.redaction
|
||||
#[ruma_enum(rename = "m.room.redaction")]
|
||||
RoomRedaction,
|
||||
|
||||
/// m.room.server_acl
|
||||
#[ruma_enum(rename = "m.room.server_acl")]
|
||||
RoomServerAcl,
|
||||
|
||||
/// m.room.third_party_invite
|
||||
#[ruma_enum(rename = "m.room.third_party_invite")]
|
||||
RoomThirdPartyInvite,
|
||||
|
||||
/// m.room.tombstone
|
||||
#[ruma_enum(rename = "m.room.tombstone")]
|
||||
RoomTombstone,
|
||||
|
||||
/// m.room.topic
|
||||
#[ruma_enum(rename = "m.room.topic")]
|
||||
RoomTopic,
|
||||
|
||||
/// m.room_key
|
||||
#[ruma_enum(rename = "m.room_key")]
|
||||
RoomKey,
|
||||
|
||||
/// m.room_key_request
|
||||
#[ruma_enum(rename = "m.room_key_request")]
|
||||
RoomKeyRequest,
|
||||
|
||||
/// m.sticker
|
||||
#[ruma_enum(rename = "m.sticker")]
|
||||
Sticker,
|
||||
|
||||
/// m.tag
|
||||
#[ruma_enum(rename = "m.tag")]
|
||||
Tag,
|
||||
|
||||
/// m.typing
|
||||
#[ruma_enum(rename = "m.typing")]
|
||||
Typing,
|
||||
|
||||
#[doc(hidden)]
|
||||
_Custom(String),
|
||||
}
|
||||
|
||||
impl EventType {
|
||||
/// Creates a string slice from this `EventType`.
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.as_ref()
|
||||
}
|
||||
|
||||
/// Creates a byte slice from this `EventType`.
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
self.as_str().as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ruma_serde::test::serde_json_eq;
|
||||
use serde_json::json;
|
||||
|
||||
use super::EventType;
|
||||
|
||||
#[test]
|
||||
fn serialize_and_deserialize_from_display_form() {
|
||||
serde_json_eq(EventType::CallAnswer, json!("m.call.answer"));
|
||||
serde_json_eq(EventType::CallCandidates, json!("m.call.candidates"));
|
||||
serde_json_eq(EventType::CallHangup, json!("m.call.hangup"));
|
||||
serde_json_eq(EventType::CallInvite, json!("m.call.invite"));
|
||||
serde_json_eq(EventType::Direct, json!("m.direct"));
|
||||
serde_json_eq(EventType::Dummy, json!("m.dummy"));
|
||||
serde_json_eq(EventType::ForwardedRoomKey, json!("m.forwarded_room_key"));
|
||||
serde_json_eq(EventType::FullyRead, json!("m.fully_read"));
|
||||
serde_json_eq(EventType::KeyVerificationAccept, json!("m.key.verification.accept"));
|
||||
serde_json_eq(EventType::KeyVerificationCancel, json!("m.key.verification.cancel"));
|
||||
serde_json_eq(EventType::KeyVerificationDone, json!("m.key.verification.done"));
|
||||
serde_json_eq(EventType::KeyVerificationKey, json!("m.key.verification.key"));
|
||||
serde_json_eq(EventType::KeyVerificationMac, json!("m.key.verification.mac"));
|
||||
serde_json_eq(EventType::KeyVerificationReady, json!("m.key.verification.ready"));
|
||||
serde_json_eq(EventType::KeyVerificationRequest, json!("m.key.verification.request"));
|
||||
serde_json_eq(EventType::KeyVerificationStart, json!("m.key.verification.start"));
|
||||
serde_json_eq(EventType::IgnoredUserList, json!("m.ignored_user_list"));
|
||||
serde_json_eq(EventType::PolicyRuleRoom, json!("m.policy.rule.room"));
|
||||
serde_json_eq(EventType::PolicyRuleServer, json!("m.policy.rule.server"));
|
||||
serde_json_eq(EventType::PolicyRuleUser, json!("m.policy.rule.user"));
|
||||
serde_json_eq(EventType::Presence, json!("m.presence"));
|
||||
serde_json_eq(EventType::PushRules, json!("m.push_rules"));
|
||||
serde_json_eq(EventType::Receipt, json!("m.receipt"));
|
||||
serde_json_eq(EventType::RoomAliases, json!("m.room.aliases"));
|
||||
serde_json_eq(EventType::RoomAvatar, json!("m.room.avatar"));
|
||||
serde_json_eq(EventType::RoomCanonicalAlias, json!("m.room.canonical_alias"));
|
||||
serde_json_eq(EventType::RoomCreate, json!("m.room.create"));
|
||||
serde_json_eq(EventType::RoomEncrypted, json!("m.room.encrypted"));
|
||||
serde_json_eq(EventType::RoomEncryption, json!("m.room.encryption"));
|
||||
serde_json_eq(EventType::RoomGuestAccess, json!("m.room.guest_access"));
|
||||
serde_json_eq(EventType::RoomHistoryVisibility, json!("m.room.history_visibility"));
|
||||
serde_json_eq(EventType::RoomJoinRules, json!("m.room.join_rules"));
|
||||
serde_json_eq(EventType::RoomMember, json!("m.room.member"));
|
||||
serde_json_eq(EventType::RoomMessage, json!("m.room.message"));
|
||||
serde_json_eq(EventType::RoomMessageFeedback, json!("m.room.message.feedback"));
|
||||
serde_json_eq(EventType::RoomName, json!("m.room.name"));
|
||||
serde_json_eq(EventType::RoomPinnedEvents, json!("m.room.pinned_events"));
|
||||
serde_json_eq(EventType::RoomPowerLevels, json!("m.room.power_levels"));
|
||||
serde_json_eq(EventType::RoomRedaction, json!("m.room.redaction"));
|
||||
serde_json_eq(EventType::RoomServerAcl, json!("m.room.server_acl"));
|
||||
serde_json_eq(EventType::RoomThirdPartyInvite, json!("m.room.third_party_invite"));
|
||||
serde_json_eq(EventType::RoomTombstone, json!("m.room.tombstone"));
|
||||
serde_json_eq(EventType::RoomTopic, json!("m.room.topic"));
|
||||
serde_json_eq(EventType::RoomKey, json!("m.room_key"));
|
||||
serde_json_eq(EventType::RoomKeyRequest, json!("m.room_key_request"));
|
||||
serde_json_eq(EventType::Sticker, json!("m.sticker"));
|
||||
serde_json_eq(EventType::Tag, json!("m.tag"));
|
||||
serde_json_eq(EventType::Typing, json!("m.typing"));
|
||||
serde_json_eq(EventType::_Custom("io.ruma.test".into()), json!("io.ruma.test"));
|
||||
}
|
||||
}
|
@ -131,7 +131,6 @@ use self::room::redaction::{RedactionEvent, SyncRedactionEvent};
|
||||
mod enums;
|
||||
mod error;
|
||||
mod event_kinds;
|
||||
mod event_type;
|
||||
|
||||
// Hack to allow both ruma-events itself and external crates (or tests) to use procedural macros
|
||||
// that expect `ruma_events` to exist in the prelude.
|
||||
@ -145,6 +144,7 @@ extern crate self as ruma_events;
|
||||
pub mod exports {
|
||||
pub use ruma_common;
|
||||
pub use ruma_identifiers;
|
||||
pub use ruma_serde;
|
||||
pub use serde;
|
||||
pub use serde_json;
|
||||
}
|
||||
@ -194,7 +194,9 @@ pub use self::{
|
||||
AnyRoomAccountDataEvent, AnyRoomAccountDataEventContent, AnyRoomEvent, AnyStateEvent,
|
||||
AnyStateEventContent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent,
|
||||
AnySyncMessageEvent, AnySyncRoomEvent, AnySyncStateEvent, AnyToDeviceEvent,
|
||||
AnyToDeviceEventContent,
|
||||
AnyToDeviceEventContent, EphemeralRoomEventType, EventType, GlobalAccountDataEventType,
|
||||
MessageEventType, RoomAccountDataEventType, RoomEventType, StateEventType,
|
||||
ToDeviceEventType,
|
||||
},
|
||||
error::{FromStrError, InvalidInput},
|
||||
event_kinds::{
|
||||
@ -204,7 +206,6 @@ pub use self::{
|
||||
StrippedStateEvent, SyncEphemeralRoomEvent, SyncMessageEvent, SyncStateEvent,
|
||||
ToDeviceEvent,
|
||||
},
|
||||
event_type::EventType,
|
||||
};
|
||||
|
||||
/// Extra information about an event that is not incorporated into the event's
|
||||
|
@ -2,6 +2,7 @@ use js_int::uint;
|
||||
use matches::assert_matches;
|
||||
use ruma_common::MilliSecondsSinceUnixEpoch;
|
||||
use ruma_identifiers::{event_id, room_alias_id, room_id, user_id};
|
||||
use ruma_serde::test::serde_json_eq;
|
||||
use serde_json::{from_value as from_json_value, json, Value as JsonValue};
|
||||
|
||||
use ruma_events::{
|
||||
@ -11,8 +12,9 @@ use ruma_events::{
|
||||
power_levels::PowerLevelsEventContent,
|
||||
},
|
||||
AnyEphemeralRoomEvent, AnyMessageEvent, AnyRoomEvent, AnyStateEvent, AnyStateEventContent,
|
||||
AnySyncMessageEvent, AnySyncRoomEvent, AnySyncStateEvent, MessageEvent, StateEvent,
|
||||
SyncMessageEvent, SyncStateEvent, Unsigned,
|
||||
AnySyncMessageEvent, AnySyncRoomEvent, AnySyncStateEvent, EphemeralRoomEventType, EventType,
|
||||
GlobalAccountDataEventType, MessageEvent, MessageEventType, RoomAccountDataEventType,
|
||||
StateEvent, StateEventType, SyncMessageEvent, SyncStateEvent, ToDeviceEventType, Unsigned,
|
||||
};
|
||||
|
||||
fn message_event() -> JsonValue {
|
||||
@ -316,3 +318,64 @@ fn ephemeral_event_deserialization() {
|
||||
if ephem.room_id() == &room_id!("!jEsUZKDJdhlrceRyVU:example.org")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_and_deserialize_from_display_form() {
|
||||
serde_json_eq(EventType::CallAnswer, json!("m.call.answer"));
|
||||
serde_json_eq(MessageEventType::CallAnswer, json!("m.call.answer"));
|
||||
serde_json_eq(EventType::CallCandidates, json!("m.call.candidates"));
|
||||
serde_json_eq(EventType::CallHangup, json!("m.call.hangup"));
|
||||
serde_json_eq(EventType::CallInvite, json!("m.call.invite"));
|
||||
serde_json_eq(EventType::Direct, json!("m.direct"));
|
||||
serde_json_eq(GlobalAccountDataEventType::Direct, json!("m.direct"));
|
||||
serde_json_eq(EventType::Dummy, json!("m.dummy"));
|
||||
serde_json_eq(EventType::ForwardedRoomKey, json!("m.forwarded_room_key"));
|
||||
serde_json_eq(EventType::FullyRead, json!("m.fully_read"));
|
||||
serde_json_eq(RoomAccountDataEventType::FullyRead, json!("m.fully_read"));
|
||||
serde_json_eq(EventType::KeyVerificationAccept, json!("m.key.verification.accept"));
|
||||
serde_json_eq(EventType::KeyVerificationCancel, json!("m.key.verification.cancel"));
|
||||
// m.key.verification.ready is unstable-pre-spec
|
||||
// serde_json_eq(EventType::KeyVerificationDone, json!("m.key.verification.done"));
|
||||
serde_json_eq(EventType::KeyVerificationKey, json!("m.key.verification.key"));
|
||||
serde_json_eq(ToDeviceEventType::KeyVerificationKey, json!("m.key.verification.key"));
|
||||
serde_json_eq(EventType::KeyVerificationMac, json!("m.key.verification.mac"));
|
||||
// m.key.verification.ready is unstable-pre-spec
|
||||
// serde_json_eq(EventType::KeyVerificationReady, json!("m.key.verification.ready"));
|
||||
serde_json_eq(EventType::KeyVerificationRequest, json!("m.key.verification.request"));
|
||||
serde_json_eq(EventType::KeyVerificationStart, json!("m.key.verification.start"));
|
||||
serde_json_eq(EventType::IgnoredUserList, json!("m.ignored_user_list"));
|
||||
serde_json_eq(EventType::PolicyRuleRoom, json!("m.policy.rule.room"));
|
||||
serde_json_eq(EventType::PolicyRuleServer, json!("m.policy.rule.server"));
|
||||
serde_json_eq(EventType::PolicyRuleUser, json!("m.policy.rule.user"));
|
||||
serde_json_eq(EventType::Presence, json!("m.presence"));
|
||||
serde_json_eq(EventType::PushRules, json!("m.push_rules"));
|
||||
serde_json_eq(EventType::Receipt, json!("m.receipt"));
|
||||
serde_json_eq(EventType::RoomAliases, json!("m.room.aliases"));
|
||||
serde_json_eq(EventType::RoomAvatar, json!("m.room.avatar"));
|
||||
serde_json_eq(EventType::RoomCanonicalAlias, json!("m.room.canonical_alias"));
|
||||
serde_json_eq(EventType::RoomCreate, json!("m.room.create"));
|
||||
serde_json_eq(StateEventType::RoomCreate, json!("m.room.create"));
|
||||
serde_json_eq(EventType::RoomEncrypted, json!("m.room.encrypted"));
|
||||
serde_json_eq(EventType::RoomEncryption, json!("m.room.encryption"));
|
||||
serde_json_eq(EventType::RoomGuestAccess, json!("m.room.guest_access"));
|
||||
serde_json_eq(EventType::RoomHistoryVisibility, json!("m.room.history_visibility"));
|
||||
serde_json_eq(EventType::RoomJoinRules, json!("m.room.join_rules"));
|
||||
serde_json_eq(EventType::RoomMember, json!("m.room.member"));
|
||||
serde_json_eq(EventType::RoomMessage, json!("m.room.message"));
|
||||
serde_json_eq(EventType::RoomMessageFeedback, json!("m.room.message.feedback"));
|
||||
serde_json_eq(EventType::RoomName, json!("m.room.name"));
|
||||
serde_json_eq(EventType::RoomPinnedEvents, json!("m.room.pinned_events"));
|
||||
serde_json_eq(EventType::RoomPowerLevels, json!("m.room.power_levels"));
|
||||
serde_json_eq(EventType::RoomRedaction, json!("m.room.redaction"));
|
||||
serde_json_eq(EventType::RoomServerAcl, json!("m.room.server_acl"));
|
||||
serde_json_eq(EventType::RoomThirdPartyInvite, json!("m.room.third_party_invite"));
|
||||
serde_json_eq(EventType::RoomTombstone, json!("m.room.tombstone"));
|
||||
serde_json_eq(EventType::RoomTopic, json!("m.room.topic"));
|
||||
serde_json_eq(EventType::RoomKey, json!("m.room_key"));
|
||||
serde_json_eq(EventType::RoomKeyRequest, json!("m.room_key_request"));
|
||||
serde_json_eq(EventType::Sticker, json!("m.sticker"));
|
||||
serde_json_eq(EventType::Tag, json!("m.tag"));
|
||||
serde_json_eq(EventType::Typing, json!("m.typing"));
|
||||
serde_json_eq(EphemeralRoomEventType::Typing, json!("m.typing"));
|
||||
serde_json_eq(EventType::_Custom("io.ruma.test".into()), json!("io.ruma.test"));
|
||||
}
|
||||
|
@ -2,15 +2,14 @@ use ruma_events_macros::event_enum;
|
||||
|
||||
event_enum! {
|
||||
/// Any global account data event.
|
||||
kind: GlobalAccountData,
|
||||
events: [
|
||||
enum GlobalAccountData {
|
||||
"m.direct",
|
||||
#[cfg(test)]
|
||||
"m.ignored_user_list",
|
||||
"m.push_rules",
|
||||
#[cfg(any())]
|
||||
"m.ruma_test",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,17 +1,15 @@
|
||||
use ruma_events_macros::event_enum;
|
||||
|
||||
event_enum! {
|
||||
kind: State,
|
||||
events: [
|
||||
enum State {
|
||||
"m.not.a.path",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
event_enum! {
|
||||
kind: State,
|
||||
events: [
|
||||
enum State {
|
||||
"not.a.path",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: well-known matrix events have to start with `m.` found `not.a.path`
|
||||
--> $DIR/08-enum-invalid-path.rs:13:9
|
||||
--> $DIR/08-enum-invalid-path.rs:11:9
|
||||
|
|
||||
13 | "not.a.path",
|
||||
11 | "not.a.path",
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0433]: failed to resolve: could not find `not` in `ruma_events`
|
||||
--> $DIR/08-enum-invalid-path.rs:6:9
|
||||
--> $DIR/08-enum-invalid-path.rs:5:9
|
||||
|
|
||||
6 | "m.not.a.path",
|
||||
5 | "m.not.a.path",
|
||||
| ^^^^^^^^^^^^^^ could not find `not` in `ruma_events`
|
||||
|
@ -1,14 +1,13 @@
|
||||
use ruma_events_macros::event_enum;
|
||||
|
||||
event_enum! {
|
||||
kind: NotReal,
|
||||
events: [
|
||||
enum NotReal {
|
||||
"m.direct",
|
||||
"m.dummy",
|
||||
"m.ignored_user_list",
|
||||
"m.push_rules",
|
||||
"m.room_key",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: valid event kinds are GlobalAccountData, RoomAccountData, EphemeralRoom, Message, State, ToDevice found `NotReal`
|
||||
--> $DIR/09-enum-invalid-kind.rs:4:18
|
||||
--> $DIR/09-enum-invalid-kind.rs:4:10
|
||||
|
|
||||
4 | kind: NotReal,
|
||||
| ^
|
||||
4 | enum NotReal {
|
||||
| ^^^^^^^
|
||||
|
Loading…
x
Reference in New Issue
Block a user