From 7957dd6adfdb64ccd451c9d5e5f5f69f0edbabdf Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 5 Sep 2022 11:16:30 +0200 Subject: [PATCH] events: Replace generic "alias" trait implementations by individual ones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … so that rustdoc lists types implementing them properly. --- crates/ruma-common/src/events/_custom.rs | 29 +++-- crates/ruma-common/src/events/content.rs | 31 ++--- crates/ruma-common/src/events/kinds.rs | 110 ++++++++++-------- crates/ruma-common/src/events/room/aliases.rs | 6 +- crates/ruma-common/src/events/room/member.rs | 6 +- crates/ruma-macros/src/events/event.rs | 21 ++-- .../ruma-macros/src/events/event_content.rs | 27 +++-- 7 files changed, 129 insertions(+), 101 deletions(-) diff --git a/crates/ruma-common/src/events/_custom.rs b/crates/ruma-common/src/events/_custom.rs index f3104ad8..644421af 100644 --- a/crates/ruma-common/src/events/_custom.rs +++ b/crates/ruma-common/src/events/_custom.rs @@ -2,9 +2,11 @@ use serde::Serialize; use serde_json::value::RawValue as RawJsonValue; use super::{ - EphemeralRoomEventType, EventContent, GlobalAccountDataEventType, HasDeserializeFields, - MessageLikeEventType, RedactContent, RedactedEventContent, RoomAccountDataEventType, - StateEventContent, StateEventType, ToDeviceEventType, + EphemeralRoomEventContent, EphemeralRoomEventType, EventContent, GlobalAccountDataEventContent, + GlobalAccountDataEventType, HasDeserializeFields, MessageLikeEventContent, + MessageLikeEventType, RedactContent, RedactedEventContent, RedactedMessageLikeEventContent, + RedactedStateEventContent, RoomAccountDataEventContent, RoomAccountDataEventType, + StateEventContent, StateEventType, ToDeviceEventContent, ToDeviceEventType, }; use crate::RoomVersionId; @@ -63,12 +65,23 @@ macro_rules! custom_room_event_content { } 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); +impl GlobalAccountDataEventContent for CustomGlobalAccountDataEventContent {} +custom_event_content!(CustomRoomAccountDataEventContent, RoomAccountDataEventType); +impl RoomAccountDataEventContent for CustomRoomAccountDataEventContent {} + +custom_event_content!(CustomEphemeralRoomEventContent, EphemeralRoomEventType); +impl EphemeralRoomEventContent for CustomEphemeralRoomEventContent {} + +custom_room_event_content!(CustomMessageLikeEventContent, MessageLikeEventType); +impl MessageLikeEventContent for CustomMessageLikeEventContent {} +impl RedactedMessageLikeEventContent for CustomMessageLikeEventContent {} + +custom_room_event_content!(CustomStateEventContent, StateEventType); impl StateEventContent for CustomStateEventContent { type StateKey = String; } +impl RedactedStateEventContent for CustomStateEventContent {} + +custom_event_content!(CustomToDeviceEventContent, ToDeviceEventType); +impl ToDeviceEventContent for CustomToDeviceEventContent {} diff --git a/crates/ruma-common/src/events/content.rs b/crates/ruma-common/src/events/content.rs index 573bcccc..1d244b0c 100644 --- a/crates/ruma-common/src/events/content.rs +++ b/crates/ruma-common/src/events/content.rs @@ -136,39 +136,32 @@ pub enum EventKind { Presence, } -/// An alias for `EventContent`. +/// Content of a global account-data event. pub trait GlobalAccountDataEventContent: EventContent { } -impl> GlobalAccountDataEventContent for T {} -/// An alias for `EventContent`. +/// Content of a room-specific account-data event. pub trait RoomAccountDataEventContent: EventContent {} -impl> RoomAccountDataEventContent for T {} -/// An alias for `EventContent`. +/// Content of an ephemeral room event. pub trait EphemeralRoomEventContent: EventContent {} -impl> EphemeralRoomEventContent for T {} -/// An alias for `EventContent`. +/// Content of a non-redacted message-like event. pub trait MessageLikeEventContent: EventContent {} -impl> MessageLikeEventContent for T {} -/// An alias for `MessageLikeEventContent + RedactedEventContent`. +/// Content of a redacted message-like event. pub trait RedactedMessageLikeEventContent: MessageLikeEventContent + RedactedEventContent {} -impl RedactedMessageLikeEventContent for T {} -/// An alias for `StateEventContent + RedactedEventContent`. -pub trait RedactedStateEventContent: StateEventContent + RedactedEventContent {} -impl RedactedStateEventContent for T {} - -/// An alias for `EventContent`. -pub trait ToDeviceEventContent: EventContent {} -impl> ToDeviceEventContent for T {} - -/// An alias for `EventContent`. +/// Content of a redacted state event. pub trait StateEventContent: EventContent { /// The type of the event's `state_key` field. type StateKey: AsRef + Clone + fmt::Debug + DeserializeOwned + Serialize; } + +/// Content of a non-redacted state event. +pub trait RedactedStateEventContent: StateEventContent + RedactedEventContent {} + +/// Content of a to-device event. +pub trait ToDeviceEventContent: EventContent {} diff --git a/crates/ruma-common/src/events/kinds.rs b/crates/ruma-common/src/events/kinds.rs index 44bb3a80..0352447c 100644 --- a/crates/ruma-common/src/events/kinds.rs +++ b/crates/ruma-common/src/events/kinds.rs @@ -7,10 +7,9 @@ use serde_json::value::RawValue as RawJsonValue; use super::{ room::redaction::SyncRoomRedactionEvent, EphemeralRoomEventContent, EventContent, GlobalAccountDataEventContent, MessageLikeEventContent, MessageLikeEventType, - MessageLikeUnsigned, Redact, RedactContent, RedactedEventContent, - RedactedMessageLikeEventContent, RedactedStateEventContent, RedactedUnsigned, - RedactionDeHelper, RoomAccountDataEventContent, StateEventContent, StateEventType, - StateUnsigned, ToDeviceEventContent, + MessageLikeUnsigned, Redact, RedactContent, RedactedMessageLikeEventContent, + RedactedStateEventContent, RedactedUnsigned, RedactionDeHelper, RoomAccountDataEventContent, + StateEventContent, StateEventType, StateUnsigned, ToDeviceEventContent, }; use crate::{ serde::from_raw_json_value, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, @@ -151,7 +150,7 @@ pub struct RedactedSyncMessageLikeEvent { #[serde(untagged)] pub enum MessageLikeEvent where - C::Redacted: MessageLikeEventContent + RedactedEventContent, + C::Redacted: RedactedMessageLikeEventContent, { /// Original, unredacted form of the event. Original(OriginalMessageLikeEvent), @@ -169,7 +168,7 @@ where #[serde(untagged)] pub enum SyncMessageLikeEvent where - C::Redacted: MessageLikeEventContent + RedactedEventContent, + C::Redacted: RedactedMessageLikeEventContent, { /// Original, unredacted form of the event. Original(OriginalSyncMessageLikeEvent), @@ -336,7 +335,7 @@ pub struct RedactedSyncStateEvent { #[serde(untagged)] pub enum StateEvent where - C::Redacted: StateEventContent + RedactedEventContent, + C::Redacted: RedactedStateEventContent, { /// Original, unredacted form of the event. Original(OriginalStateEvent), @@ -354,7 +353,7 @@ where #[serde(untagged)] pub enum SyncStateEvent where - C::Redacted: StateEventContent + RedactedEventContent, + C::Redacted: RedactedStateEventContent, { /// Original, unredacted form of the event. Original(OriginalSyncStateEvent), @@ -411,14 +410,14 @@ pub struct DecryptedMegolmV1Event { macro_rules! impl_possibly_redacted_event { ( - $ty:ident ( $content_trait:ident, $event_type:ident ) + $ty:ident ( $content_trait:ident, $redacted_content_trait:ident, $event_type:ident ) $( where C::Redacted: $trait:ident, )? { $($extra:tt)* } ) => { impl $ty where C: $content_trait + RedactContent, - C::Redacted: $content_trait + RedactedEventContent, + C::Redacted: $redacted_content_trait, $( C::Redacted: $trait, )? { /// Returns the `type` of this event. @@ -460,7 +459,7 @@ macro_rules! impl_possibly_redacted_event { impl Redact for $ty where C: $content_trait + RedactContent, - C::Redacted: $content_trait + RedactedEventContent, + C::Redacted: $redacted_content_trait, $( C::Redacted: $trait, )? { type Redacted = Self; @@ -476,7 +475,7 @@ macro_rules! impl_possibly_redacted_event { impl<'de, C> Deserialize<'de> for $ty where C: $content_trait + RedactContent, - C::Redacted: $content_trait + RedactedEventContent, + C::Redacted: $redacted_content_trait, $( C::Redacted: $trait, )? { fn deserialize(deserializer: D) -> Result @@ -496,44 +495,52 @@ macro_rules! impl_possibly_redacted_event { } } -impl_possibly_redacted_event!(MessageLikeEvent(MessageLikeEventContent, MessageLikeEventType) { - /// Returns this event's `room_id` field. - pub fn room_id(&self) -> &RoomId { - match self { - Self::Original(ev) => &ev.room_id, - Self::Redacted(ev) => &ev.room_id, +impl_possibly_redacted_event!( + MessageLikeEvent( + MessageLikeEventContent, RedactedMessageLikeEventContent, MessageLikeEventType + ) { + /// Returns this event's `room_id` field. + pub fn room_id(&self) -> &RoomId { + match self { + Self::Original(ev) => &ev.room_id, + Self::Redacted(ev) => &ev.room_id, + } } - } - /// Get the inner `OriginalMessageLikeEvent` if this is an unredacted event. - pub fn as_original(&self) -> Option<&OriginalMessageLikeEvent> { - match self { - Self::Original(v) => Some(v), - _ => None, + /// Get the inner `OriginalMessageLikeEvent` if this is an unredacted event. + pub fn as_original(&self) -> Option<&OriginalMessageLikeEvent> { + match self { + Self::Original(v) => Some(v), + _ => None, + } } } -}); - -impl_possibly_redacted_event!(SyncMessageLikeEvent(MessageLikeEventContent, MessageLikeEventType) { - /// Get the inner `OriginalSyncMessageLikeEvent` if this is an unredacted event. - pub fn as_original(&self) -> Option<&OriginalSyncMessageLikeEvent> { - match self { - Self::Original(v) => Some(v), - _ => None, - } - } - - /// Convert this sync event into a full event (one with a `room_id` field). - pub fn into_full_event(self, room_id: OwnedRoomId) -> MessageLikeEvent { - match self { - Self::Original(ev) => MessageLikeEvent::Original(ev.into_full_event(room_id)), - Self::Redacted(ev) => MessageLikeEvent::Redacted(ev.into_full_event(room_id)), - } - } -}); +); impl_possibly_redacted_event!( - StateEvent(StateEventContent, StateEventType) + SyncMessageLikeEvent( + MessageLikeEventContent, RedactedMessageLikeEventContent, MessageLikeEventType + ) { + /// Get the inner `OriginalSyncMessageLikeEvent` if this is an unredacted event. + pub fn as_original(&self) -> Option<&OriginalSyncMessageLikeEvent> { + match self { + Self::Original(v) => Some(v), + _ => None, + } + } + + /// Convert this sync event into a full event (one with a `room_id` field). + pub fn into_full_event(self, room_id: OwnedRoomId) -> MessageLikeEvent { + match self { + Self::Original(ev) => MessageLikeEvent::Original(ev.into_full_event(room_id)), + Self::Redacted(ev) => MessageLikeEvent::Redacted(ev.into_full_event(room_id)), + } + } + } +); + +impl_possibly_redacted_event!( + StateEvent(StateEventContent, RedactedStateEventContent, StateEventType) where C::Redacted: StateEventContent, { @@ -564,7 +571,7 @@ impl_possibly_redacted_event!( ); impl_possibly_redacted_event!( - SyncStateEvent(StateEventContent, StateEventType) + SyncStateEvent(StateEventContent, RedactedStateEventContent, StateEventType) where C::Redacted: StateEventContent, { @@ -595,11 +602,11 @@ impl_possibly_redacted_event!( ); macro_rules! impl_sync_from_full { - ($ty:ident, $full:ident, $content_trait:ident) => { + ($ty:ident, $full:ident, $content_trait:ident, $redacted_content_trait: ident) => { impl From<$full> for $ty where C: $content_trait + RedactContent, - C::Redacted: $content_trait + RedactedEventContent, + C::Redacted: $redacted_content_trait, { fn from(full: $full) -> Self { match full { @@ -611,5 +618,10 @@ macro_rules! impl_sync_from_full { }; } -impl_sync_from_full!(SyncMessageLikeEvent, MessageLikeEvent, MessageLikeEventContent); -impl_sync_from_full!(SyncStateEvent, StateEvent, StateEventContent); +impl_sync_from_full!( + SyncMessageLikeEvent, + MessageLikeEvent, + MessageLikeEventContent, + RedactedMessageLikeEventContent +); +impl_sync_from_full!(SyncStateEvent, StateEvent, StateEventContent, RedactedStateEventContent); diff --git a/crates/ruma-common/src/events/room/aliases.rs b/crates/ruma-common/src/events/room/aliases.rs index 287306f5..0c76a39a 100644 --- a/crates/ruma-common/src/events/room/aliases.rs +++ b/crates/ruma-common/src/events/room/aliases.rs @@ -6,8 +6,8 @@ use serde_json::value::RawValue as RawJsonValue; use crate::{ events::{ - EventContent, HasDeserializeFields, RedactContent, RedactedEventContent, StateEventContent, - StateEventType, + EventContent, HasDeserializeFields, RedactContent, RedactedEventContent, + RedactedStateEventContent, StateEventContent, StateEventType, }, OwnedRoomAliasId, OwnedServerName, RoomVersionId, }; @@ -99,6 +99,8 @@ impl StateEventContent for RedactedRoomAliasesEventContent { type StateKey = OwnedServerName; } +impl RedactedStateEventContent for RedactedRoomAliasesEventContent {} + // Since this redacted event has fields we leave the default `empty` method // that will error if called. impl RedactedEventContent for RedactedRoomAliasesEventContent { diff --git a/crates/ruma-common/src/events/room/member.rs b/crates/ruma-common/src/events/room/member.rs index 9a19b83e..b6f9fe25 100644 --- a/crates/ruma-common/src/events/room/member.rs +++ b/crates/ruma-common/src/events/room/member.rs @@ -10,8 +10,8 @@ use serde_json::value::RawValue as RawJsonValue; use crate::{ events::{ - EventContent, HasDeserializeFields, RedactContent, RedactedEventContent, StateEventContent, - StateEventType, + EventContent, HasDeserializeFields, RedactContent, RedactedEventContent, + RedactedStateEventContent, StateEventContent, StateEventType, }, serde::StringEnum, OwnedMxcUri, OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, PrivOwnedStr, @@ -204,6 +204,8 @@ impl StateEventContent for RedactedRoomMemberEventContent { type StateKey = OwnedUserId; } +impl RedactedStateEventContent for RedactedRoomMemberEventContent {} + // Since this redacted event has fields we leave the default `empty` method // that will error if called. impl RedactedEventContent for RedactedRoomMemberEventContent { diff --git a/crates/ruma-macros/src/events/event.rs b/crates/ruma-macros/src/events/event.rs index 344a2166..fbf93688 100644 --- a/crates/ruma-macros/src/events/event.rs +++ b/crates/ruma-macros/src/events/event.rs @@ -1,7 +1,7 @@ //! Implementation of the top level `*Event` derive macro. use proc_macro2::{Span, TokenStream}; -use quote::quote; +use quote::{format_ident, quote}; use syn::{parse_quote, Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, GenericParam}; use super::{ @@ -359,7 +359,6 @@ fn expand_redact_event( ruma_common: &TokenStream, ) -> syn::Result { let redacted_type = kind.to_event_ident(var.to_redacted())?; - let redacted_event_type_enum = kind.to_event_type_enum(); let ident = &input.ident; let mut generics = input.generics.clone(); @@ -376,20 +375,14 @@ fn expand_redact_event( let where_clause = generics.make_where_clause(); where_clause.predicates.push(parse_quote! { #ty_param: #ruma_common::events::RedactContent }); - let redacted_event_content_bound = if kind == EventKind::State { - quote! { - #ruma_common::events::StateEventContent - } - } else { - quote! { - #ruma_common::events::EventContent< - EventType = #ruma_common::events::#redacted_event_type_enum - > - } + let assoc_type_bounds = + (kind == EventKind::State).then(|| quote! { StateKey = #ty_param::StateKey }); + let trait_name = format_ident!("Redacted{kind}Content"); + let redacted_event_content_bound = quote! { + #ruma_common::events::#trait_name<#assoc_type_bounds> }; where_clause.predicates.push(parse_quote! { - <#ty_param as #ruma_common::events::RedactContent>::Redacted: - #redacted_event_content_bound + #ruma_common::events::RedactedEventContent + <#ty_param as #ruma_common::events::RedactContent>::Redacted: #redacted_event_content_bound }); let (impl_generics, ty_gen, where_clause) = generics.split_for_impl(); diff --git a/crates/ruma-macros/src/events/event_content.rs b/crates/ruma-macros/src/events/event_content.rs index baba5a50..d2d6be5c 100644 --- a/crates/ruma-macros/src/events/event_content.rs +++ b/crates/ruma-macros/src/events/event_content.rs @@ -407,8 +407,10 @@ fn generate_redacted_event_content<'a>( ) .unwrap_or_else(syn::Error::into_compile_error); - let static_event_content_impl = event_kind.map(|k| { - generate_static_event_content_impl(&redacted_ident, k, true, event_type, ruma_common) + let sub_trait_name = event_kind.map(|kind| format_ident!("Redacted{kind}Content")); + + let static_event_content_impl = event_kind.map(|kind| { + generate_static_event_content_impl(&redacted_ident, kind, true, event_type, ruma_common) }); let mut event_types = aliases.to_owned(); @@ -460,6 +462,9 @@ fn generate_redacted_event_content<'a>( } } + #[automatically_derived] + impl #ruma_common::events::#sub_trait_name for #redacted_ident {} + #static_event_content_impl }) } @@ -611,12 +616,20 @@ fn generate_event_content_impl<'a>( } } - let state_event_content_impl = (event_kind == Some(EventKind::State)).then(|| { - assert!(state_key_type.is_some()); + let sub_trait_impl = event_kind.map(|kind| { + let trait_name = format_ident!("{kind}Content"); + + let state_event_content_impl = (event_kind == Some(EventKind::State)).then(|| { + assert!(state_key_type.is_some()); + quote! { + type StateKey = #state_key_type; + } + }); + quote! { #[automatically_derived] - impl #ruma_common::events::StateEventContent for #ident { - type StateKey = #state_key_type; + impl #ruma_common::events::#trait_name for #ident { + #state_event_content_impl } } }); @@ -682,7 +695,7 @@ fn generate_event_content_impl<'a>( } } - #state_event_content_impl + #sub_trait_impl }) }