Use *EventType enums in more places

This commit is contained in:
Jonas Platte 2022-03-15 13:26:13 +01:00
parent 0f18deae1d
commit 6dc0bf248b
No known key found for this signature in database
GPG Key ID: BBA95679259D342F
14 changed files with 99 additions and 62 deletions

View File

@ -36,7 +36,7 @@ pub mod v3 {
/// ///
/// Custom types should be namespaced to avoid clashes. /// Custom types should be namespaced to avoid clashes.
#[ruma_api(path)] #[ruma_api(path)]
pub event_type: &'a str, pub event_type: GlobalAccountDataEventType,
/// Arbitrary JSON to store as config data. /// Arbitrary JSON to store as config data.
/// ///
@ -72,7 +72,7 @@ pub mod v3 {
/// Creates a new `Request` with the given raw data, event type and user ID. /// Creates a new `Request` with the given raw data, event type and user ID.
pub fn new_raw( pub fn new_raw(
data: Raw<AnyGlobalAccountDataEventContent>, data: Raw<AnyGlobalAccountDataEventContent>,
event_type: &'a str, event_type: GlobalAccountDataEventType,
user_id: &'a UserId, user_id: &'a UserId,
) -> Self { ) -> Self {
Self { user_id, event_type, data } Self { user_id, event_type, data }

View File

@ -36,7 +36,7 @@ pub mod v3 {
/// ///
/// Custom types should be namespaced to avoid clashes. /// Custom types should be namespaced to avoid clashes.
#[ruma_api(path)] #[ruma_api(path)]
pub event_type: &'a str, pub event_type: RoomAccountDataEventType,
/// The ID of the room to set account_data on. /// The ID of the room to set account_data on.
#[ruma_api(path)] #[ruma_api(path)]
@ -81,7 +81,7 @@ pub mod v3 {
/// Creates a new `Request` with the given raw data, event type, room ID and user ID. /// Creates a new `Request` with the given raw data, event type, room ID and user ID.
pub fn new_raw( pub fn new_raw(
data: Raw<AnyRoomAccountDataEventContent>, data: Raw<AnyRoomAccountDataEventContent>,
event_type: &'a str, event_type: RoomAccountDataEventType,
room_id: &'a RoomId, room_id: &'a RoomId,
user_id: &'a UserId, user_id: &'a UserId,
) -> Self { ) -> Self {

View File

@ -32,7 +32,7 @@ pub mod v3 {
/// The type of event to send. /// The type of event to send.
#[ruma_api(path)] #[ruma_api(path)]
pub event_type: &'a str, pub event_type: MessageLikeEventType,
/// The transaction ID for this event. /// The transaction ID for this event.
/// ///
@ -83,7 +83,7 @@ pub mod v3 {
pub fn new_raw( pub fn new_raw(
room_id: &'a RoomId, room_id: &'a RoomId,
txn_id: &'a TransactionId, txn_id: &'a TransactionId,
event_type: &'a str, event_type: MessageLikeEventType,
body: Raw<AnyMessageLikeEventContent>, body: Raw<AnyMessageLikeEventContent>,
) -> Self { ) -> Self {
Self { room_id, event_type, txn_id, body } Self { room_id, event_type, txn_id, body }

View File

@ -44,7 +44,7 @@ pub mod v3 {
pub room_id: &'a RoomId, pub room_id: &'a RoomId,
/// The type of event to send. /// The type of event to send.
pub event_type: &'a str, pub event_type: StateEventType,
/// The state_key for the state to send. /// The state_key for the state to send.
pub state_key: &'a str, pub state_key: &'a str,
@ -80,7 +80,7 @@ pub mod v3 {
/// content. /// content.
pub fn new_raw( pub fn new_raw(
room_id: &'a RoomId, room_id: &'a RoomId,
event_type: &'a str, event_type: StateEventType,
state_key: &'a str, state_key: &'a str,
body: Raw<AnyStateEventContent>, body: Raw<AnyStateEventContent>,
) -> Self { ) -> Self {
@ -114,7 +114,8 @@ pub mod v3 {
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
let room_id_percent = utf8_percent_encode(self.room_id.as_str(), NON_ALPHANUMERIC); let room_id_percent = utf8_percent_encode(self.room_id.as_str(), NON_ALPHANUMERIC);
let event_type_percent = utf8_percent_encode(self.event_type, NON_ALPHANUMERIC); let event_type_percent =
utf8_percent_encode(self.event_type.as_str(), NON_ALPHANUMERIC);
let mut url = format!( let mut url = format!(
"{}{}", "{}{}",
@ -173,9 +174,8 @@ pub mod v3 {
{ {
// FIXME: find a way to make this if-else collapse with serde recognizing trailing // FIXME: find a way to make this if-else collapse with serde recognizing trailing
// Option // Option
let (room_id, event_type, state_key): (Box<RoomId>, String, String) = if path_args.len() let (room_id, event_type, state_key): (Box<RoomId>, StateEventType, String) =
== 3 if path_args.len() == 3 {
{
serde::Deserialize::deserialize(serde::de::value::SeqDeserializer::< serde::Deserialize::deserialize(serde::de::value::SeqDeserializer::<
_, _,
serde::de::value::Error, serde::de::value::Error,
@ -183,7 +183,8 @@ pub mod v3 {
path_args.iter().map(::std::convert::AsRef::as_ref), path_args.iter().map(::std::convert::AsRef::as_ref),
))? ))?
} else { } else {
let (a, b) = serde::Deserialize::deserialize(serde::de::value::SeqDeserializer::< let (a, b) =
serde::Deserialize::deserialize(serde::de::value::SeqDeserializer::<
_, _,
serde::de::value::Error, serde::de::value::Error,
>::new( >::new(

View File

@ -202,10 +202,10 @@ pub use self::{
/// Use [`macros::EventContent`] to derive this traits. It is not meant to be implemented manually. /// Use [`macros::EventContent`] to derive this traits. It is not meant to be implemented manually.
pub trait EventContent: Sized + Serialize { pub trait EventContent: Sized + Serialize {
/// The Rust enum for the event kind's known types. /// The Rust enum for the event kind's known types.
type EventType; type EventType: AsRef<str>;
/// Get the event's type, like `m.room.message`. /// Get the event's type, like `m.room.message`.
fn event_type(&self) -> &str; fn event_type(&self) -> Self::EventType;
/// Constructs the given event content. /// Constructs the given event content.
#[doc(hidden)] #[doc(hidden)]
@ -240,8 +240,8 @@ pub trait RedactContent {
impl<T: EventContent> Raw<T> { impl<T: EventContent> Raw<T> {
/// Try to deserialize the JSON as an event's content. /// Try to deserialize the JSON as an event's content.
pub fn deserialize_content(&self, event_type: &str) -> serde_json::Result<T> { pub fn deserialize_content(&self, event_type: T::EventType) -> serde_json::Result<T> {
T::from_parts(event_type, self.json()) T::from_parts(event_type.as_ref(), self.json())
} }
} }

View File

@ -23,8 +23,8 @@ macro_rules! custom_event_content {
impl EventContent for $i { impl EventContent for $i {
type EventType = $evt; type EventType = $evt;
fn event_type(&self) -> &str { fn event_type(&self) -> Self::EventType {
&self.event_type self.event_type[..].into()
} }
fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> { fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {

View File

@ -78,8 +78,8 @@ impl RedactedRoomAliasesEventContent {
impl EventContent for RedactedRoomAliasesEventContent { impl EventContent for RedactedRoomAliasesEventContent {
type EventType = StateEventType; type EventType = StateEventType;
fn event_type(&self) -> &str { fn event_type(&self) -> StateEventType {
"m.room.aliases" StateEventType::RoomAliases
} }
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> { fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {

View File

@ -161,8 +161,8 @@ impl RedactedRoomMemberEventContent {
impl EventContent for RedactedRoomMemberEventContent { impl EventContent for RedactedRoomMemberEventContent {
type EventType = StateEventType; type EventType = StateEventType;
fn event_type(&self) -> &str { fn event_type(&self) -> StateEventType {
"m.room.member" StateEventType::RoomMember
} }
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> { fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {

View File

@ -299,7 +299,7 @@ fn alias_event_field_access() {
} else { } else {
panic!("the `Any*Event` enum's accessor methods may have been altered") panic!("the `Any*Event` enum's accessor methods may have been altered")
} }
assert_eq!(deser.event_type(), "m.room.aliases"); assert_eq!(deser.event_type().as_str(), "m.room.aliases");
} }
#[test] #[test]

View File

@ -8,7 +8,7 @@ use ruma_common::{
room::{ImageInfo, ThumbnailInfo}, room::{ImageInfo, ThumbnailInfo},
sticker::StickerEventContent, sticker::StickerEventContent,
AnyMessageLikeEvent, AnyMessageLikeEventContent, AnySyncMessageLikeEvent, MessageLikeEvent, AnyMessageLikeEvent, AnyMessageLikeEventContent, AnySyncMessageLikeEvent, MessageLikeEvent,
Unsigned, MessageLikeEventType, Unsigned,
}, },
mxc_uri, room_id, mxc_uri, room_id,
serde::Raw, serde::Raw,
@ -86,7 +86,7 @@ fn deserialize_message_call_answer_content() {
assert_matches!( assert_matches!(
from_json_value::<Raw<AnyMessageLikeEventContent>>(json_data) from_json_value::<Raw<AnyMessageLikeEventContent>>(json_data)
.unwrap() .unwrap()
.deserialize_content("m.call.answer") .deserialize_content(MessageLikeEventType::CallAnswer)
.unwrap(), .unwrap(),
AnyMessageLikeEventContent::CallAnswer(CallAnswerEventContent { AnyMessageLikeEventContent::CallAnswer(CallAnswerEventContent {
answer: SessionDescription { answer: SessionDescription {

View File

@ -9,7 +9,7 @@ use ruma_common::{
ThumbnailInfo, ThumbnailInfo,
}, },
AnyRoomEvent, AnyStateEvent, AnyStateEventContent, AnySyncStateEvent, StateEvent, AnyRoomEvent, AnyStateEvent, AnyStateEventContent, AnySyncStateEvent, StateEvent,
SyncStateEvent, Unsigned, StateEventType, SyncStateEvent, Unsigned,
}, },
mxc_uri, room_alias_id, room_id, mxc_uri, room_alias_id, room_id,
serde::Raw, serde::Raw,
@ -99,7 +99,7 @@ fn deserialize_aliases_content() {
assert_matches!( assert_matches!(
from_json_value::<Raw<AnyStateEventContent>>(json_data) from_json_value::<Raw<AnyStateEventContent>>(json_data)
.unwrap() .unwrap()
.deserialize_content("m.room.aliases") .deserialize_content(StateEventType::RoomAliases)
.unwrap(), .unwrap(),
AnyStateEventContent::RoomAliases(content) AnyStateEventContent::RoomAliases(content)
if content.aliases == vec![room_alias_id!("#somewhere:localhost")] if content.aliases == vec![room_alias_id!("#somewhere:localhost")]

View File

@ -120,6 +120,8 @@ fn expand_serialize_event(
use #serde::ser::{SerializeStruct as _, Error as _}; use #serde::ser::{SerializeStruct as _, Error as _};
let event_type = #ruma_common::events::EventContent::event_type(&self.content); let event_type = #ruma_common::events::EventContent::event_type(&self.content);
let event_type =
::std::convert::AsRef::<::std::primitive::str>::as_ref(&event_type);
let mut state = serializer.serialize_struct(stringify!(#ident), 7)?; let mut state = serializer.serialize_struct(stringify!(#ident), 7)?;

View File

@ -9,6 +9,8 @@ use syn::{
DeriveInput, Ident, LitStr, Token, DeriveInput, Ident, LitStr, Token,
}; };
use crate::util::m_prefix_name_to_type_name;
use super::event_parse::{EventKind, EventKindVariation}; use super::event_parse::{EventKind, EventKindVariation};
mod kw { mod kw {
@ -164,7 +166,7 @@ pub fn expand_event_content(
.transpose()?; .transpose()?;
let event_content_impl = let event_content_impl =
generate_event_content_impl(ident, event_type, event_kind, ruma_common); generate_event_content_impl(ident, event_type, event_kind, ruma_common)?;
let static_event_content_impl = event_kind let static_event_content_impl = event_kind
.map(|k| generate_static_event_content_impl(ident, k, false, event_type, ruma_common)); .map(|k| generate_static_event_content_impl(ident, k, false, event_type, ruma_common));
let type_aliases = event_kind let type_aliases = event_kind
@ -259,7 +261,7 @@ fn generate_redacted_event_content(
}); });
let redacted_event_content = let redacted_event_content =
generate_event_content_impl(&redacted_ident, event_type, event_kind, ruma_common); generate_event_content_impl(&redacted_ident, event_type, event_kind, ruma_common)?;
let static_event_content_impl = event_kind.map(|k| { let static_event_content_impl = event_kind.map(|k| {
generate_static_event_content_impl(&redacted_ident, k, true, event_type, ruma_common) generate_static_event_content_impl(&redacted_ident, k, true, event_type, ruma_common)
@ -374,41 +376,66 @@ fn generate_event_content_impl(
event_type: &LitStr, event_type: &LitStr,
event_kind: Option<EventKind>, event_kind: Option<EventKind>,
ruma_common: &TokenStream, ruma_common: &TokenStream,
) -> TokenStream { ) -> syn::Result<TokenStream> {
let serde = quote! { #ruma_common::exports::serde }; let serde = quote! { #ruma_common::exports::serde };
let serde_json = quote! { #ruma_common::exports::serde_json }; let serde_json = quote! { #ruma_common::exports::serde_json };
let event_type_ty = match event_kind { let (event_type_ty_decl, event_type_ty, event_type_fn_impl);
match event_kind {
Some(kind) => { Some(kind) => {
let i = kind.to_event_type_enum(); let i = kind.to_event_type_enum();
quote! { #ruma_common::events::#i } event_type_ty_decl = None;
event_type_ty = quote! { #ruma_common::events::#i };
event_type_fn_impl = quote! { ::std::convert::From::from(#event_type) };
}
None => {
let camel_case_type_name = m_prefix_name_to_type_name(event_type)?;
let i = format_ident!("{}EventType", camel_case_type_name);
event_type_ty_decl = Some(quote! {
/// Implementation detail, you don't need to care about this.
#[doc(hidden)]
pub struct #i {
// Set to None for intended type, Some for a different one
ty: ::std::option::Option<crate::PrivOwnedStr>,
} }
None => quote! { () },
};
quote! { impl ::std::convert::AsRef<::std::primitive::str> for #i {
fn as_ref(&self) -> &::std::primitive::str {
self.ty.as_ref().map(|t| &t.0[..]).unwrap_or(#event_type)
}
}
});
event_type_ty = quote! { #i };
event_type_fn_impl = quote! { #event_type_ty { ty: ::std::option::Option::None } };
}
}
Ok(quote! {
#event_type_ty_decl
#[automatically_derived] #[automatically_derived]
impl #ruma_common::events::EventContent for #ident { impl #ruma_common::events::EventContent for #ident {
type EventType = #event_type_ty; type EventType = #event_type_ty;
fn event_type(&self) -> &str { fn event_type(&self) -> Self::EventType {
#event_type #event_type_fn_impl
} }
fn from_parts( fn from_parts(
ev_type: &str, ev_type: &::std::primitive::str,
content: &#serde_json::value::RawValue, content: &#serde_json::value::RawValue,
) -> #serde_json::Result<Self> { ) -> #serde_json::Result<Self> {
if ev_type != #event_type { if ev_type != #event_type {
return Err(#serde::de::Error::custom( return ::std::result::Result::Err(#serde::de::Error::custom(
format!("expected event type `{}`, found `{}`", #event_type, ev_type) ::std::format!("expected event type `{}`, found `{}`", #event_type, ev_type)
)); ));
} }
#serde_json::from_str(content.get()) #serde_json::from_str(content.get())
} }
} }
} })
} }
fn generate_static_event_content_impl( fn generate_static_event_content_impl(

View File

@ -292,10 +292,10 @@ fn expand_content_enum(
impl #ruma_common::events::EventContent for #ident { impl #ruma_common::events::EventContent for #ident {
type EventType = #ruma_common::events::#event_type_enum; type EventType = #ruma_common::events::#event_type_enum;
fn event_type(&self) -> &::std::primitive::str { fn event_type(&self) -> Self::EventType {
match self { match self {
#( #variant_arms(content) => content.event_type(), )* #( #variant_arms(content) => content.event_type(), )*
Self::_Custom { event_type } => &event_type.0, Self::_Custom { event_type } => ::std::convert::From::from(&event_type.0[..]),
} }
} }
@ -411,6 +411,7 @@ fn expand_accessor_methods(
ruma_common: &TokenStream, ruma_common: &TokenStream,
) -> TokenStream { ) -> TokenStream {
let ident = kind.to_event_enum_ident(var); let ident = kind.to_event_enum_ident(var);
let event_type_enum = format_ident!("{}Type", kind);
let self_variants: Vec<_> = variants.iter().map(|v| v.match_arm(quote! { Self })).collect(); let self_variants: Vec<_> = variants.iter().map(|v| v.match_arm(quote! { Self })).collect();
let content_accessors = (!var.is_redacted()).then(|| { let content_accessors = (!var.is_redacted()).then(|| {
@ -430,7 +431,9 @@ fn expand_accessor_methods(
Self::_Custom(event) => { Self::_Custom(event) => {
event.prev_content.as_ref().map(|c| #content_enum::_Custom { event.prev_content.as_ref().map(|c| #content_enum::_Custom {
event_type: crate::PrivOwnedStr( event_type: crate::PrivOwnedStr(
#ruma_common::events::EventContent::event_type(c).into(), ::std::convert::From::from(
#ruma_common::events::EventContent::event_type(c).as_str()
),
), ),
}) })
}, },
@ -446,7 +449,10 @@ fn expand_accessor_methods(
#( #self_variants(event) => #content_variants(event.content.clone()), )* #( #self_variants(event) => #content_variants(event.content.clone()), )*
Self::_Custom(event) => #content_enum::_Custom { Self::_Custom(event) => #content_enum::_Custom {
event_type: crate::PrivOwnedStr( event_type: crate::PrivOwnedStr(
#ruma_common::events::EventContent::event_type(&event.content).into(), ::std::convert::From::from(
#ruma_common::events::EventContent::event_type(&event.content)
.as_str(),
),
), ),
}, },
} }
@ -479,12 +485,13 @@ fn expand_accessor_methods(
#[automatically_derived] #[automatically_derived]
impl #ident { impl #ident {
/// Returns the `type` of this event. /// Returns the `type` of this event.
pub fn event_type(&self) -> &::std::primitive::str { pub fn event_type(&self) -> #ruma_common::events::#event_type_enum {
match self { match self {
#( #self_variants(event) => #( #self_variants(event) =>
#ruma_common::events::EventContent::event_type(&event.content), )* #ruma_common::events::EventContent::event_type(&event.content), )*
Self::_Custom(event) => Self::_Custom(event) => ::std::convert::From::from(
#ruma_common::events::EventContent::event_type(&event.content), #ruma_common::events::EventContent::event_type(&event.content),
),
} }
} }