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.
#[ruma_api(path)]
pub event_type: &'a str,
pub event_type: GlobalAccountDataEventType,
/// 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.
pub fn new_raw(
data: Raw<AnyGlobalAccountDataEventContent>,
event_type: &'a str,
event_type: GlobalAccountDataEventType,
user_id: &'a UserId,
) -> Self {
Self { user_id, event_type, data }

View File

@ -36,7 +36,7 @@ pub mod v3 {
///
/// Custom types should be namespaced to avoid clashes.
#[ruma_api(path)]
pub event_type: &'a str,
pub event_type: RoomAccountDataEventType,
/// The ID of the room to set account_data on.
#[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.
pub fn new_raw(
data: Raw<AnyRoomAccountDataEventContent>,
event_type: &'a str,
event_type: RoomAccountDataEventType,
room_id: &'a RoomId,
user_id: &'a UserId,
) -> Self {

View File

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

View File

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

View File

@ -202,10 +202,10 @@ pub use self::{
/// Use [`macros::EventContent`] to derive this traits. It is not meant to be implemented manually.
pub trait EventContent: Sized + Serialize {
/// 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`.
fn event_type(&self) -> &str;
fn event_type(&self) -> Self::EventType;
/// Constructs the given event content.
#[doc(hidden)]
@ -240,8 +240,8 @@ pub trait RedactContent {
impl<T: EventContent> Raw<T> {
/// Try to deserialize the JSON as an event's content.
pub fn deserialize_content(&self, event_type: &str) -> serde_json::Result<T> {
T::from_parts(event_type, self.json())
pub fn deserialize_content(&self, event_type: T::EventType) -> serde_json::Result<T> {
T::from_parts(event_type.as_ref(), self.json())
}
}

View File

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

View File

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

View File

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

View File

@ -299,7 +299,7 @@ fn alias_event_field_access() {
} else {
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]

View File

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

View File

@ -9,7 +9,7 @@ use ruma_common::{
ThumbnailInfo,
},
AnyRoomEvent, AnyStateEvent, AnyStateEventContent, AnySyncStateEvent, StateEvent,
SyncStateEvent, Unsigned,
StateEventType, SyncStateEvent, Unsigned,
},
mxc_uri, room_alias_id, room_id,
serde::Raw,
@ -99,7 +99,7 @@ fn deserialize_aliases_content() {
assert_matches!(
from_json_value::<Raw<AnyStateEventContent>>(json_data)
.unwrap()
.deserialize_content("m.room.aliases")
.deserialize_content(StateEventType::RoomAliases)
.unwrap(),
AnyStateEventContent::RoomAliases(content)
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 _};
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)?;

View File

@ -9,6 +9,8 @@ use syn::{
DeriveInput, Ident, LitStr, Token,
};
use crate::util::m_prefix_name_to_type_name;
use super::event_parse::{EventKind, EventKindVariation};
mod kw {
@ -164,7 +166,7 @@ pub fn expand_event_content(
.transpose()?;
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
.map(|k| generate_static_event_content_impl(ident, k, false, event_type, ruma_common));
let type_aliases = event_kind
@ -259,7 +261,7 @@ fn generate_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| {
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_kind: Option<EventKind>,
ruma_common: &TokenStream,
) -> TokenStream {
) -> syn::Result<TokenStream> {
let serde = quote! { #ruma_common::exports::serde };
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) => {
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 => quote! { () },
};
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>,
}
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
quote! {
#[automatically_derived]
impl #ruma_common::events::EventContent for #ident {
type EventType = #event_type_ty;
fn event_type(&self) -> &str {
#event_type
fn event_type(&self) -> Self::EventType {
#event_type_fn_impl
}
fn from_parts(
ev_type: &str,
ev_type: &::std::primitive::str,
content: &#serde_json::value::RawValue,
) -> #serde_json::Result<Self> {
if ev_type != #event_type {
return Err(#serde::de::Error::custom(
format!("expected event type `{}`, found `{}`", #event_type, ev_type)
return ::std::result::Result::Err(#serde::de::Error::custom(
::std::format!("expected event type `{}`, found `{}`", #event_type, ev_type)
));
}
#serde_json::from_str(content.get())
}
}
}
})
}
fn generate_static_event_content_impl(

View File

@ -292,10 +292,10 @@ fn expand_content_enum(
impl #ruma_common::events::EventContent for #ident {
type EventType = #ruma_common::events::#event_type_enum;
fn event_type(&self) -> &::std::primitive::str {
fn event_type(&self) -> Self::EventType {
match self {
#( #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,
) -> TokenStream {
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 content_accessors = (!var.is_redacted()).then(|| {
@ -430,7 +431,9 @@ fn expand_accessor_methods(
Self::_Custom(event) => {
event.prev_content.as_ref().map(|c| #content_enum::_Custom {
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::_Custom(event) => #content_enum::_Custom {
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]
impl #ident {
/// 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 {
#( #self_variants(event) =>
#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),
),
}
}