From 6279a2fa6f264cbc2dc16c25622ec3be6da2a026 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 29 Mar 2022 21:43:49 +0200 Subject: [PATCH] events: Move EventContent trait and related items into new module --- crates/ruma-common/src/events.rs | 136 +---------------------- crates/ruma-common/src/events/content.rs | 133 ++++++++++++++++++++++ 2 files changed, 137 insertions(+), 132 deletions(-) create mode 100644 crates/ruma-common/src/events/content.rs diff --git a/crates/ruma-common/src/events.rs b/crates/ruma-common/src/events.rs index f70b2826..805880ad 100644 --- a/crates/ruma-common/src/events.rs +++ b/crates/ruma-common/src/events.rs @@ -126,17 +126,15 @@ //! type alias), allowing content to be converted to and from JSON independently of the surrounding //! event structure, if needed. -use std::fmt; - -use serde::{de::IgnoredAny, Deserialize, Serialize, Serializer}; -use serde_json::value::RawValue as RawJsonValue; +use serde::{de::IgnoredAny, Deserialize, Serializer}; use self::room::redaction::SyncRoomRedactionEvent; -use crate::{serde::Raw, EventEncryptionAlgorithm, RoomVersionId}; +use crate::{EventEncryptionAlgorithm, RoomVersionId}; // Needs to be public for trybuild tests #[doc(hidden)] pub mod _custom; +mod content; mod enums; mod event_kinds; mod unsigned; @@ -193,26 +191,12 @@ pub mod voice; #[cfg(feature = "unstable-msc2675")] pub use self::relation::Relations; pub use self::{ + content::*, enums::*, event_kinds::*, unsigned::{MessageLikeUnsigned, RedactedUnsigned, StateUnsigned}, }; -/// The base trait that all event content types implement. -/// -/// 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; - - /// Get the event's type, like `m.room.message`. - fn event_type(&self) -> Self::EventType; - - /// Constructs the given event content. - #[doc(hidden)] - fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result; -} - /// Trait to define the behavior of redacting an event. pub trait Redact { /// The redacted form of the event. @@ -239,118 +223,6 @@ pub trait RedactContent { fn redact(self, version: &RoomVersionId) -> Self::Redacted; } -impl Raw -where - T: EventContent, - T::EventType: fmt::Display, -{ - /// Try to deserialize the JSON as an event's content. - pub fn deserialize_content(&self, event_type: T::EventType) -> serde_json::Result { - T::from_parts(&event_type.to_string(), self.json()) - } -} - -/// The base trait that all redacted event content types implement. -/// -/// This trait's associated functions and methods should not be used to build -/// redacted events, prefer the `redact` method on `AnyStateEvent` and -/// `AnyMessageLikeEvent` and their "sync" and "stripped" counterparts. The -/// `RedactedEventContent` trait is an implementation detail, ruma makes no -/// API guarantees. -pub trait RedactedEventContent: EventContent { - /// Constructs the redacted event content. - /// - /// If called for anything but "empty" redacted content this will error. - #[doc(hidden)] - fn empty(_event_type: &str) -> serde_json::Result { - Err(serde::de::Error::custom("this event is not redacted")) - } - - /// Determines if the redacted event content needs to serialize fields. - #[doc(hidden)] - fn has_serialize_fields(&self) -> bool; - - /// Determines if the redacted event content needs to deserialize fields. - #[doc(hidden)] - fn has_deserialize_fields() -> HasDeserializeFields; -} - -/// 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 -/// fixed / known at compile time. -pub trait StaticEventContent: EventContent { - /// The event's "kind". - /// - /// See the type's documentation. - const KIND: EventKind; - - /// The event type. - const TYPE: &'static str; -} - -/// The "kind" of an event. -/// -/// This corresponds directly to the event content marker traits. -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[non_exhaustive] -pub enum EventKind { - /// Global account data event kind. - GlobalAccountData, - - /// Room account data event kind. - RoomAccountData, - - /// Ephemeral room event kind. - EphemeralRoomData, - - /// Message-like event kind. - /// - /// Since redacted / non-redacted message-like events are used in the same places but have - /// different sets of fields, these two variations are treated as two closely-related event - /// kinds. - MessageLike { - /// Redacted variation? - redacted: bool, - }, - - /// State event kind. - /// - /// Since redacted / non-redacted state events are used in the same places but have different - /// sets of fields, these two variations are treated as two closely-related event kinds. - State { - /// Redacted variation? - redacted: bool, - }, - - /// To-device event kind. - ToDevice, - - /// Presence event kind. - Presence, - - /// Hierarchy space child kind. - HierarchySpaceChild, -} - -/// `HasDeserializeFields` is used in the code generated by the `Event` derive -/// to aid in deserializing redacted events. -#[doc(hidden)] -#[derive(Debug)] -#[allow(clippy::exhaustive_enums)] -pub enum HasDeserializeFields { - /// Deserialize the event's content, failing if invalid. - True, - - /// Return the redacted version of this event's content. - False, - - /// `Optional` is used for `RedactedAliasesEventContent` since it has - /// an empty version and one with content left after redaction that - /// must be supported together. - Optional, -} - /// Helper struct to determine the event kind from a `serde_json::value::RawValue`. #[doc(hidden)] #[derive(Deserialize)] diff --git a/crates/ruma-common/src/events/content.rs b/crates/ruma-common/src/events/content.rs new file mode 100644 index 00000000..06f06aae --- /dev/null +++ b/crates/ruma-common/src/events/content.rs @@ -0,0 +1,133 @@ +use std::fmt; + +use serde::Serialize; +use serde_json::value::RawValue as RawJsonValue; + +use crate::serde::Raw; + +/// The base trait that all event content types implement. +/// +/// 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; + + /// Get the event's type, like `m.room.message`. + fn event_type(&self) -> Self::EventType; + + /// Constructs the given event content. + #[doc(hidden)] + fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result; +} + +impl Raw +where + T: EventContent, + T::EventType: fmt::Display, +{ + /// Try to deserialize the JSON as an event's content. + pub fn deserialize_content(&self, event_type: T::EventType) -> serde_json::Result { + T::from_parts(&event_type.to_string(), self.json()) + } +} + +/// The base trait that all redacted event content types implement. +/// +/// This trait's associated functions and methods should not be used to build +/// redacted events, prefer the `redact` method on `AnyStateEvent` and +/// `AnyMessageLikeEvent` and their "sync" and "stripped" counterparts. The +/// `RedactedEventContent` trait is an implementation detail, ruma makes no +/// API guarantees. +pub trait RedactedEventContent: EventContent { + /// Constructs the redacted event content. + /// + /// If called for anything but "empty" redacted content this will error. + #[doc(hidden)] + fn empty(_event_type: &str) -> serde_json::Result { + Err(serde::de::Error::custom("this event is not redacted")) + } + + /// Determines if the redacted event content needs to serialize fields. + #[doc(hidden)] + fn has_serialize_fields(&self) -> bool; + + /// Determines if the redacted event content needs to deserialize fields. + #[doc(hidden)] + fn has_deserialize_fields() -> HasDeserializeFields; +} + +/// `HasDeserializeFields` is used in the code generated by the `Event` derive +/// to aid in deserializing redacted events. +#[doc(hidden)] +#[derive(Debug)] +#[allow(clippy::exhaustive_enums)] +pub enum HasDeserializeFields { + /// Deserialize the event's content, failing if invalid. + True, + + /// Return the redacted version of this event's content. + False, + + /// `Optional` is used for `RedactedAliasesEventContent` since it has + /// an empty version and one with content left after redaction that + /// must be supported together. + Optional, +} + +/// 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 +/// fixed / known at compile time. +pub trait StaticEventContent: EventContent { + /// The event's "kind". + /// + /// See the type's documentation. + const KIND: EventKind; + + /// The event type. + const TYPE: &'static str; +} + +/// The "kind" of an event. +/// +/// This corresponds directly to the event content marker traits. +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[non_exhaustive] +pub enum EventKind { + /// Global account data event kind. + GlobalAccountData, + + /// Room account data event kind. + RoomAccountData, + + /// Ephemeral room event kind. + EphemeralRoomData, + + /// Message-like event kind. + /// + /// Since redacted / non-redacted message-like events are used in the same places but have + /// different sets of fields, these two variations are treated as two closely-related event + /// kinds. + MessageLike { + /// Redacted variation? + redacted: bool, + }, + + /// State event kind. + /// + /// Since redacted / non-redacted state events are used in the same places but have different + /// sets of fields, these two variations are treated as two closely-related event kinds. + State { + /// Redacted variation? + redacted: bool, + }, + + /// To-device event kind. + ToDevice, + + /// Presence event kind. + Presence, + + /// Hierarchy space child kind. + HierarchySpaceChild, +}