common: Replace event content marker traits with an associated type

This commit is contained in:
Jonas Platte 2022-03-15 13:02:21 +01:00
parent 8805b8f2e3
commit c16ba45c9e
No known key found for this signature in database
GPG Key ID: BBA95679259D342F
18 changed files with 158 additions and 201 deletions

View File

@ -7,7 +7,7 @@ pub mod v3 {
use ruma_common::{
api::ruma_api,
events::{AnyGlobalAccountDataEventContent, GlobalAccountDataEventContent},
events::{AnyGlobalAccountDataEventContent, EventContent, GlobalAccountDataEventType},
serde::Raw,
UserId,
};
@ -58,10 +58,10 @@ pub mod v3 {
///
/// Since `Request` stores the request body in serialized form, this function can fail if
/// `T`s [`Serialize`][serde::Serialize] implementation can fail.
pub fn new<T: GlobalAccountDataEventContent>(
data: &'a T,
user_id: &'a UserId,
) -> serde_json::Result<Self> {
pub fn new<T>(data: &'a T, user_id: &'a UserId) -> serde_json::Result<Self>
where
T: EventContent<EventType = GlobalAccountDataEventType>,
{
Ok(Self {
user_id,
event_type: data.event_type(),

View File

@ -7,7 +7,7 @@ pub mod v3 {
use ruma_common::{
api::ruma_api,
events::{AnyRoomAccountDataEventContent, RoomAccountDataEventContent},
events::{AnyRoomAccountDataEventContent, EventContent, RoomAccountDataEventType},
serde::Raw,
RoomId, UserId,
};
@ -62,11 +62,14 @@ pub mod v3 {
///
/// Since `Request` stores the request body in serialized form, this function can fail if
/// `T`s [`Serialize`][serde::Serialize] implementation can fail.
pub fn new<T: RoomAccountDataEventContent>(
pub fn new<T>(
data: &'a T,
room_id: &'a RoomId,
user_id: &'a UserId,
) -> serde_json::Result<Self> {
) -> serde_json::Result<Self>
where
T: EventContent<EventType = RoomAccountDataEventType>,
{
Ok(Self {
data: Raw::from_json(to_raw_json_value(data)?),
event_type: data.event_type(),

View File

@ -7,7 +7,7 @@ pub mod v3 {
use ruma_common::{
api::ruma_api,
events::{AnyMessageLikeEventContent, MessageLikeEventContent},
events::{AnyMessageLikeEventContent, EventContent, MessageLikeEventType},
serde::Raw,
EventId, RoomId, TransactionId,
};
@ -62,11 +62,14 @@ pub mod v3 {
///
/// Since `Request` stores the request body in serialized form, this function can fail if
/// `T`s [`Serialize`][serde::Serialize] implementation can fail.
pub fn new<T: MessageLikeEventContent>(
pub fn new<T>(
room_id: &'a RoomId,
txn_id: &'a TransactionId,
content: &'a T,
) -> serde_json::Result<Self> {
) -> serde_json::Result<Self>
where
T: EventContent<EventType = MessageLikeEventType>,
{
Ok(Self {
room_id,
txn_id,

View File

@ -7,7 +7,7 @@ pub mod v3 {
use ruma_common::{
api::ruma_api,
events::{AnyStateEventContent, StateEventContent},
events::{AnyStateEventContent, EventContent, StateEventType},
serde::{Outgoing, Raw},
EventId, RoomId,
};
@ -60,11 +60,14 @@ pub mod v3 {
///
/// Since `Request` stores the request body in serialized form, this function can fail if
/// `T`s [`Serialize`][serde::Serialize] implementation can fail.
pub fn new<T: StateEventContent>(
pub fn new<T>(
room_id: &'a RoomId,
state_key: &'a str,
content: &'a T,
) -> serde_json::Result<Self> {
) -> serde_json::Result<Self>
where
T: EventContent<EventType = StateEventType>,
{
Ok(Self {
room_id,
state_key,

View File

@ -199,12 +199,16 @@ pub use self::{
/// The base trait that all event content types implement.
///
/// Implementing this trait allows content types to be serialized as well as deserialized.
/// Use [`macros::EventContent`] to derive this traits. It is not meant to be implemented manually.
pub trait EventContent: Sized + Serialize {
/// A matrix event identifier, like `m.room.message`.
/// The Rust enum for the event kind's known types.
type EventType;
/// Get the event's type, like `m.room.message`.
fn event_type(&self) -> &str;
/// Constructs the given event content.
#[doc(hidden)]
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self>;
}
@ -241,24 +245,6 @@ impl<T: EventContent> Raw<T> {
}
}
/// Marker trait for the content of an ephemeral room event.
pub trait EphemeralRoomEventContent: EventContent {}
/// Marker trait for the content of a global account data event.
pub trait GlobalAccountDataEventContent: EventContent {}
/// Marker trait for the content of a room account data event.
pub trait RoomAccountDataEventContent: EventContent {}
/// Marker trait for the content of a to device event.
pub trait ToDeviceEventContent: EventContent {}
/// Marker trait for the content of a message-like event.
pub trait MessageLikeEventContent: EventContent {}
/// Marker trait for the content of a state event.
pub trait StateEventContent: EventContent {}
/// The base trait that all redacted event content types implement.
///
/// This trait's associated functions and methods should not be used to build
@ -284,12 +270,6 @@ pub trait RedactedEventContent: EventContent {
fn has_deserialize_fields() -> HasDeserializeFields;
}
/// Marker trait for the content of a redacted message-like event.
pub trait RedactedMessageLikeEventContent: RedactedEventContent {}
/// Marker trait for the content of a redacted state event.
pub trait RedactedStateEventContent: RedactedEventContent {}
/// Trait for abstracting over event content structs.
///
/// … but *not* enums which don't always have an event type and kind (e.g. message vs state) that's

View File

@ -2,59 +2,69 @@ use serde::Serialize;
use serde_json::value::RawValue as RawJsonValue;
use super::{
EphemeralRoomEventContent, EventContent, GlobalAccountDataEventContent, HasDeserializeFields,
MessageLikeEventContent, RedactContent, RedactedEventContent, RedactedMessageLikeEventContent,
RedactedStateEventContent, RoomAccountDataEventContent, StateEventContent,
ToDeviceEventContent,
EphemeralRoomEventType, EventContent, GlobalAccountDataEventType, HasDeserializeFields,
MessageLikeEventType, RedactContent, RedactedEventContent, RoomAccountDataEventType,
StateEventType, ToDeviceEventType,
};
use crate::RoomVersionId;
/// A custom event's type. Used for event enum `_Custom` variants.
// FIXME: Serialize shouldn't be required here, but it's currently a supertrait of EventContent
#[derive(Clone, Debug, Serialize)]
#[allow(clippy::exhaustive_structs)]
pub struct CustomEventContent {
#[serde(skip)]
event_type: Box<str>,
macro_rules! custom_event_content {
($i:ident, $evt:ident) => {
/// A custom event's type. Used for event enum `_Custom` variants.
// FIXME: Serialize shouldn't be required here, but it's currently a supertrait of
// EventContent
#[derive(Clone, Debug, Serialize)]
#[allow(clippy::exhaustive_structs)]
pub struct $i {
#[serde(skip)]
event_type: Box<str>,
}
impl EventContent for $i {
type EventType = $evt;
fn event_type(&self) -> &str {
&self.event_type
}
fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
Ok(Self { event_type: event_type.into() })
}
}
};
}
impl RedactContent for CustomEventContent {
type Redacted = Self;
macro_rules! custom_room_event_content {
($i:ident, $evt:ident) => {
custom_event_content!($i, $evt);
fn redact(self, _: &RoomVersionId) -> Self {
self
}
impl RedactContent for $i {
type Redacted = Self;
fn redact(self, _: &RoomVersionId) -> Self {
self
}
}
impl RedactedEventContent for $i {
fn empty(event_type: &str) -> serde_json::Result<Self> {
Ok(Self { event_type: event_type.into() })
}
fn has_serialize_fields(&self) -> bool {
false
}
fn has_deserialize_fields() -> HasDeserializeFields {
HasDeserializeFields::False
}
}
};
}
impl EventContent for CustomEventContent {
fn event_type(&self) -> &str {
&self.event_type
}
fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
Ok(Self { event_type: event_type.into() })
}
}
impl RedactedEventContent for CustomEventContent {
fn empty(event_type: &str) -> serde_json::Result<Self> {
Ok(Self { event_type: event_type.into() })
}
fn has_serialize_fields(&self) -> bool {
false
}
fn has_deserialize_fields() -> HasDeserializeFields {
HasDeserializeFields::False
}
}
impl GlobalAccountDataEventContent for CustomEventContent {}
impl RoomAccountDataEventContent for CustomEventContent {}
impl ToDeviceEventContent for CustomEventContent {}
impl EphemeralRoomEventContent for CustomEventContent {}
impl MessageLikeEventContent for CustomEventContent {}
impl StateEventContent for CustomEventContent {}
impl RedactedMessageLikeEventContent for CustomEventContent {}
impl RedactedStateEventContent for CustomEventContent {}
custom_event_content!(CustomGlobalAccountDataEventContent, GlobalAccountDataEventType);
custom_event_content!(CustomRoomAccountDataEventContent, RoomAccountDataEventType);
custom_event_content!(CustomEphemeralRoomEventContent, EphemeralRoomEventType);
custom_room_event_content!(CustomMessageLikeEventContent, MessageLikeEventType);
custom_room_event_content!(CustomStateEventContent, StateEventType);
custom_event_content!(CustomToDeviceEventContent, ToDeviceEventType);

View File

@ -4,29 +4,29 @@ use ruma_macros::Event;
use serde::{Deserialize, Serialize};
use super::{
EphemeralRoomEventContent, GlobalAccountDataEventContent, MessageLikeEventContent,
RedactedMessageLikeEventContent, RedactedStateEventContent, RedactedUnsigned,
RoomAccountDataEventContent, StateEventContent, ToDeviceEventContent, Unsigned,
EphemeralRoomEventType, EventContent, GlobalAccountDataEventType, MessageLikeEventType,
RedactedEventContent, RedactedUnsigned, RoomAccountDataEventType, StateEventType,
ToDeviceEventType, Unsigned,
};
use crate::{EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId};
/// A global account data event.
#[derive(Clone, Debug, Event)]
pub struct GlobalAccountDataEvent<C: GlobalAccountDataEventContent> {
pub struct GlobalAccountDataEvent<C: EventContent<EventType = GlobalAccountDataEventType>> {
/// Data specific to the event type.
pub content: C,
}
/// A room account data event.
#[derive(Clone, Debug, Event)]
pub struct RoomAccountDataEvent<C: RoomAccountDataEventContent> {
pub struct RoomAccountDataEvent<C: EventContent<EventType = RoomAccountDataEventType>> {
/// Data specific to the event type.
pub content: C,
}
/// An ephemeral room event.
#[derive(Clone, Debug, Event)]
pub struct EphemeralRoomEvent<C: EphemeralRoomEventContent> {
pub struct EphemeralRoomEvent<C: EventContent<EventType = EphemeralRoomEventType>> {
/// Data specific to the event type.
pub content: C,
@ -36,7 +36,7 @@ pub struct EphemeralRoomEvent<C: EphemeralRoomEventContent> {
/// An ephemeral room event without a `room_id`.
#[derive(Clone, Debug, Event)]
pub struct SyncEphemeralRoomEvent<C: EphemeralRoomEventContent> {
pub struct SyncEphemeralRoomEvent<C: EventContent<EventType = EphemeralRoomEventType>> {
/// Data specific to the event type.
pub content: C,
}
@ -46,7 +46,7 @@ pub struct SyncEphemeralRoomEvent<C: EphemeralRoomEventContent> {
/// `MessageLikeEvent` implements the comparison traits using only the `event_id` field, a sorted
/// list would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct MessageLikeEvent<C: MessageLikeEventContent> {
pub struct MessageLikeEvent<C: EventContent<EventType = MessageLikeEventType>> {
/// Data specific to the event type.
pub content: C,
@ -71,7 +71,7 @@ pub struct MessageLikeEvent<C: MessageLikeEventContent> {
/// `SyncMessageLikeEvent` implements the comparison traits using only the `event_id` field, a
/// sorted list would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct SyncMessageLikeEvent<C: MessageLikeEventContent> {
pub struct SyncMessageLikeEvent<C: EventContent<EventType = MessageLikeEventType>> {
/// Data specific to the event type.
pub content: C,
@ -93,7 +93,9 @@ pub struct SyncMessageLikeEvent<C: MessageLikeEventContent> {
/// `RedactedMessageLikeEvent` implements the comparison traits using only the `event_id` field, a
/// sorted list would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct RedactedMessageLikeEvent<C: RedactedMessageLikeEventContent> {
pub struct RedactedMessageLikeEvent<
C: EventContent<EventType = MessageLikeEventType> + RedactedEventContent,
> {
/// Data specific to the event type.
pub content: C,
@ -118,7 +120,9 @@ pub struct RedactedMessageLikeEvent<C: RedactedMessageLikeEventContent> {
/// `RedactedSyncMessageLikeEvent` implements the comparison traits using only the `event_id` field,
/// a sorted list would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct RedactedSyncMessageLikeEvent<C: RedactedMessageLikeEventContent> {
pub struct RedactedSyncMessageLikeEvent<
C: EventContent<EventType = MessageLikeEventType> + RedactedEventContent,
> {
/// Data specific to the event type.
pub content: C,
@ -140,7 +144,7 @@ pub struct RedactedSyncMessageLikeEvent<C: RedactedMessageLikeEventContent> {
/// `StateEvent` implements the comparison traits using only the `event_id` field, a sorted list
/// would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct StateEvent<C: StateEventContent> {
pub struct StateEvent<C: EventContent<EventType = StateEventType>> {
/// Data specific to the event type.
pub content: C,
@ -174,7 +178,7 @@ pub struct StateEvent<C: StateEventContent> {
/// `SyncStateEvent` implements the comparison traits using only the `event_id` field, a sorted list
/// would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct SyncStateEvent<C: StateEventContent> {
pub struct SyncStateEvent<C: EventContent<EventType = StateEventType>> {
/// Data specific to the event type.
pub content: C,
@ -202,7 +206,7 @@ pub struct SyncStateEvent<C: StateEventContent> {
/// A stripped-down state event, used for previews of rooms the user has been invited to.
#[derive(Clone, Debug, Event)]
pub struct StrippedStateEvent<C: StateEventContent> {
pub struct StrippedStateEvent<C: EventContent<EventType = StateEventType>> {
/// Data specific to the event type.
pub content: C,
@ -218,7 +222,7 @@ pub struct StrippedStateEvent<C: StateEventContent> {
/// A minimal state event, used for creating a new room.
#[derive(Clone, Debug, Event)]
pub struct InitialStateEvent<C: StateEventContent> {
pub struct InitialStateEvent<C: EventContent<EventType = StateEventType>> {
/// Data specific to the event type.
pub content: C,
@ -237,7 +241,7 @@ pub struct InitialStateEvent<C: StateEventContent> {
/// `RedactedStateEvent` implements the comparison traits using only the `event_id` field, a sorted
/// list would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct RedactedStateEvent<C: RedactedStateEventContent> {
pub struct RedactedStateEvent<C: EventContent<EventType = StateEventType> + RedactedEventContent> {
/// Data specific to the event type.
pub content: C,
@ -268,7 +272,9 @@ pub struct RedactedStateEvent<C: RedactedStateEventContent> {
/// `RedactedSyncStateEvent` implements the comparison traits using only the `event_id` field, a
/// sorted list would be sorted lexicographically based on the event's `EventId`.
#[derive(Clone, Debug, Event)]
pub struct RedactedSyncStateEvent<C: RedactedStateEventContent> {
pub struct RedactedSyncStateEvent<
C: EventContent<EventType = StateEventType> + RedactedEventContent,
> {
/// Data specific to the event type.
pub content: C,
@ -293,7 +299,7 @@ pub struct RedactedSyncStateEvent<C: RedactedStateEventContent> {
/// An event sent using send-to-device messaging.
#[derive(Clone, Debug, Event)]
pub struct ToDeviceEvent<C: ToDeviceEventContent> {
pub struct ToDeviceEvent<C: EventContent<EventType = ToDeviceEventType>> {
/// Data specific to the event type.
pub content: C,
@ -303,7 +309,7 @@ pub struct ToDeviceEvent<C: ToDeviceEventContent> {
/// The decrypted payload of an `m.olm.v1.curve25519-aes-sha2` event.
#[derive(Clone, Debug, Event)]
pub struct DecryptedOlmV1Event<C: MessageLikeEventContent> {
pub struct DecryptedOlmV1Event<C: EventContent<EventType = MessageLikeEventType>> {
/// Data specific to the event type.
pub content: C,
@ -329,7 +335,7 @@ pub struct OlmV1Keys {
/// The decrypted payload of an `m.megolm.v1.aes-sha2` event.
#[derive(Clone, Debug, Event)]
pub struct DecryptedMegolmV1Event<C: MessageLikeEventContent> {
pub struct DecryptedMegolmV1Event<C: EventContent<EventType = MessageLikeEventType>> {
/// Data specific to the event type.
pub content: C,

View File

@ -6,8 +6,7 @@ use serde_json::value::RawValue as RawJsonValue;
use crate::{
events::{
EventContent, HasDeserializeFields, RedactContent, RedactedEventContent,
RedactedStateEventContent,
EventContent, HasDeserializeFields, RedactContent, RedactedEventContent, StateEventType,
},
RoomAliasId, RoomVersionId,
};
@ -77,6 +76,8 @@ impl RedactedRoomAliasesEventContent {
}
impl EventContent for RedactedRoomAliasesEventContent {
type EventType = StateEventType;
fn event_type(&self) -> &str {
"m.room.aliases"
}
@ -104,5 +105,3 @@ impl RedactedEventContent for RedactedRoomAliasesEventContent {
HasDeserializeFields::Optional
}
}
impl RedactedStateEventContent for RedactedRoomAliasesEventContent {}

View File

@ -10,8 +10,8 @@ use serde_json::value::RawValue as RawJsonValue;
use crate::{
events::{
EventContent, HasDeserializeFields, RedactContent, RedactedEventContent,
RedactedStateEventContent, StrippedStateEvent, SyncStateEvent,
EventContent, HasDeserializeFields, RedactContent, RedactedEventContent, StateEventType,
StrippedStateEvent, SyncStateEvent,
},
serde::StringEnum,
MxcUri, PrivOwnedStr, RoomVersionId, ServerName, ServerSigningKeyId, UserId,
@ -159,6 +159,8 @@ impl RedactedRoomMemberEventContent {
}
impl EventContent for RedactedRoomMemberEventContent {
type EventType = StateEventType;
fn event_type(&self) -> &str {
"m.room.member"
}
@ -187,8 +189,6 @@ impl RedactedEventContent for RedactedRoomMemberEventContent {
}
}
impl RedactedStateEventContent for RedactedRoomMemberEventContent {}
/// The membership state of a user.
///
/// This type can hold an arbitrary string. To check for formats that are not available as a

View File

@ -4,14 +4,14 @@
extern crate serde;
use ruma_common::{
events::{StateEventContent, Unsigned},
events::{EventContent, StateEventType, Unsigned},
EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
};
use ruma_macros::Event;
/// State event.
#[derive(Clone, Debug, Event)]
pub struct StateEvent<C: StateEventContent> {
pub struct StateEvent<C: EventContent<EventType = StateEventType>> {
pub content: C,
pub event_id: Box<EventId>,
pub sender: Box<UserId>,

View File

@ -1,8 +1,8 @@
use ruma_common::events::StateEventContent;
use ruma_common::events::{EventContent, StateEventType};
use ruma_macros::Event;
/// State event.
#[derive(Clone, Debug, Event)]
pub struct StateEvent<C: StateEventContent>(C);
pub struct StateEvent<C: EventContent<EventType = StateEventType>>(C);
fn main() {}

View File

@ -1,5 +1,5 @@
error: the `Event` derive only supports structs with named fields
--> $DIR/05-named-fields.rs:6:12
--> tests/events/ui/05-named-fields.rs:6:12
|
6 | pub struct StateEvent<C: StateEventContent>(C);
6 | pub struct StateEvent<C: EventContent<EventType = StateEventType>>(C);
| ^^^^^^^^^^

View File

@ -1,9 +1,9 @@
use ruma_common::events::StateEventContent;
use ruma_common::events::{EventContent, StateEventType};
use ruma_macros::Event;
/// State event.
#[derive(Clone, Debug, Event)]
pub struct StateEvent<C: StateEventContent> {
pub struct StateEvent<C: EventContent<EventType = StateEventType>> {
pub not_content: C,
}

View File

@ -1,11 +1,11 @@
error: well-known matrix events have to start with `m.` found `not.a.path`
--> $DIR/08-enum-invalid-path.rs:11:9
--> tests/events/ui/08-enum-invalid-path.rs:11:9
|
11 | "not.a.path",
| ^^^^^^^^^^^^
error[E0433]: failed to resolve: could not find `not` in `events`
--> $DIR/08-enum-invalid-path.rs:5:9
--> tests/events/ui/08-enum-invalid-path.rs:5:9
|
5 | "m.not.a.path",
| ^^^^^^^^^^^^^^ could not find `not` in `events`

View File

@ -1,7 +1,7 @@
//! Implementation of the top level `*Event` derive macro.
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote};
use quote::quote;
use syn::{
parse_quote, Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, GenericParam, Meta,
MetaList, NestedMeta,
@ -415,8 +415,7 @@ fn expand_redact_event(
ruma_common: &TokenStream,
) -> TokenStream {
let redacted_type = kind.to_event_ident(var.to_redacted());
let redacted_content_trait =
format_ident!("{}Content", kind.to_event_ident(EventKindVariation::Redacted));
let redacted_event_type_enum = kind.to_event_type_enum();
let ident = &input.ident;
let mut generics = input.generics.clone();
@ -434,7 +433,8 @@ fn expand_redact_event(
where_clause.predicates.push(parse_quote! { #ty_param: #ruma_common::events::RedactContent });
where_clause.predicates.push(parse_quote! {
<#ty_param as #ruma_common::events::RedactContent>::Redacted:
#ruma_common::events::#redacted_content_trait
#ruma_common::events::EventContent<EventType = #redacted_event_type_enum>
+ #ruma_common::events::RedactedEventContent
});
let (impl_generics, ty_gen, where_clause) = generics.split_for_impl();

View File

@ -163,11 +163,10 @@ pub fn expand_event_content(
})
.transpose()?;
let event_content_impl = generate_event_content_impl(ident, event_type, ruma_common);
let event_content_impl =
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 marker_trait_impl =
event_kind.map(|k| generate_marker_trait_impl(k, ident, ruma_common)).transpose()?;
let type_aliases = event_kind
.map(|k| generate_event_type_aliases(k, ident, &event_type.value(), ruma_common))
.transpose()?;
@ -176,7 +175,6 @@ pub fn expand_event_content(
#redacted_event_content
#event_content_impl
#static_event_content_impl
#marker_trait_impl
#type_aliases
})
}
@ -261,19 +259,7 @@ fn generate_redacted_event_content(
});
let redacted_event_content =
generate_event_content_impl(&redacted_ident, event_type, ruma_common);
let marker_trait_impl = match event_kind {
Some(EventKind::MessageLike) => quote! {
#[automatically_derived]
impl #ruma_common::events::RedactedMessageLikeEventContent for #redacted_ident {}
},
Some(EventKind::State) => quote! {
#[automatically_derived]
impl #ruma_common::events::RedactedStateEventContent for #redacted_ident {}
},
_ => TokenStream::new(),
};
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)
@ -323,7 +309,6 @@ fn generate_redacted_event_content(
}
#static_event_content_impl
#marker_trait_impl
})
}
@ -384,47 +369,28 @@ fn generate_event_type_aliases(
Ok(type_aliases)
}
fn generate_marker_trait_impl(
event_kind: EventKind,
ident: &Ident,
ruma_common: &TokenStream,
) -> syn::Result<TokenStream> {
let marker_trait = match event_kind {
EventKind::GlobalAccountData => quote! { GlobalAccountDataEventContent },
EventKind::RoomAccountData => quote! { RoomAccountDataEventContent },
EventKind::Ephemeral => quote! { EphemeralRoomEventContent },
EventKind::MessageLike => quote! { MessageLikeEventContent },
EventKind::State => quote! { StateEventContent },
EventKind::ToDevice => quote! { ToDeviceEventContent },
EventKind::RoomRedaction
| EventKind::Presence
| EventKind::Decrypted
| EventKind::HierarchySpaceChild => {
return Err(syn::Error::new_spanned(
ident,
"valid event kinds are GlobalAccountData, RoomAccountData, \
EphemeralRoom, MessageLike, State, ToDevice",
));
}
};
Ok(quote! {
#[automatically_derived]
impl #ruma_common::events::#marker_trait for #ident {}
})
}
fn generate_event_content_impl(
ident: &Ident,
event_type: &LitStr,
event_kind: Option<EventKind>,
ruma_common: &TokenStream,
) -> TokenStream {
let serde = quote! { #ruma_common::exports::serde };
let serde_json = quote! { #ruma_common::exports::serde_json };
let event_type_ty = match event_kind {
Some(kind) => {
let i = kind.to_event_type_enum();
quote! { #ruma_common::events::#i }
}
None => quote! { () },
};
quote! {
#[automatically_derived]
impl #ruma_common::events::EventContent for #ident {
type EventType = #event_type_ty;
fn event_type(&self) -> &str {
#event_type
}

View File

@ -71,6 +71,8 @@ fn expand_event_enum(
let content: Vec<_> =
events.iter().map(|event| to_event_path(event, kind, var, ruma_common)).collect();
let custom_ty = format_ident!("Custom{}Content", kind);
let deserialize_impl = expand_deserialize_impl(kind, var, events, variants, ruma_common);
let field_accessor_impl = expand_accessor_methods(kind, var, variants, ruma_common);
let from_impl = expand_from_impl(&ident, &content, variants);
@ -88,9 +90,7 @@ fn expand_event_enum(
/// An event not defined by the Matrix specification
#[doc(hidden)]
_Custom(
#ruma_common::events::#event_struct<
#ruma_common::events::_custom::CustomEventContent,
>,
#ruma_common::events::#event_struct<#ruma_common::events::_custom::#custom_ty>,
),
}
@ -250,6 +250,7 @@ fn expand_content_enum(
let ident = kind.to_content_enum();
let event_type_enum = kind.to_event_type_enum();
let event_type_str = events;
let content: Vec<_> =
@ -264,7 +265,6 @@ fn expand_content_enum(
let variant_arms = variants.iter().map(|v| v.match_arm(quote! { Self })).collect::<Vec<_>>();
let variant_ctors = variants.iter().map(|v| v.ctor(quote! { Self }));
let marker_trait_impl = expand_marker_trait_impl(kind, ruma_common);
let from_impl = expand_from_impl(&ident, &content, variants);
let serialize_custom_event_error_path =
@ -290,6 +290,8 @@ fn expand_content_enum(
#[automatically_derived]
impl #ruma_common::events::EventContent for #ident {
type EventType = #ruma_common::events::#event_type_enum;
fn event_type(&self) -> &::std::primitive::str {
match self {
#( #variant_arms(content) => content.event_type(), )*
@ -317,7 +319,6 @@ fn expand_content_enum(
}
}
#marker_trait_impl
#from_impl
}
}
@ -403,24 +404,6 @@ fn expand_possibly_redacted_enum(
}
}
fn expand_marker_trait_impl(kind: EventKind, ruma_common: &TokenStream) -> TokenStream {
let marker_trait = match kind {
EventKind::State => quote! { StateEventContent },
EventKind::MessageLike => quote! { MessageLikeEventContent },
EventKind::Ephemeral => quote! { EphemeralRoomEventContent },
EventKind::GlobalAccountData => quote! { GlobalAccountDataEventContent },
EventKind::RoomAccountData => quote! { RoomAccountDataEventContent },
EventKind::ToDevice => quote! { ToDeviceEventContent },
_ => return TokenStream::new(),
};
let ident = kind.to_content_enum();
quote! {
#[automatically_derived]
impl #ruma_common::events::#marker_trait for #ident {}
}
}
fn expand_accessor_methods(
kind: EventKind,
var: EventKindVariation,

View File

@ -152,6 +152,10 @@ impl EventKind {
format_ident!("Any{}", self.to_event_ident(var))
}
pub fn to_event_type_enum(self) -> Ident {
format_ident!("{}Type", self)
}
/// `Any[kind]EventContent`
pub fn to_content_enum(self) -> Ident {
format_ident!("Any{}Content", self)