events: Move EventContent trait and related items into new module
This commit is contained in:
parent
36aa0cb3cf
commit
6279a2fa6f
@ -126,17 +126,15 @@
|
|||||||
//! type alias), allowing content to be converted to and from JSON independently of the surrounding
|
//! type alias), allowing content to be converted to and from JSON independently of the surrounding
|
||||||
//! event structure, if needed.
|
//! event structure, if needed.
|
||||||
|
|
||||||
use std::fmt;
|
use serde::{de::IgnoredAny, Deserialize, Serializer};
|
||||||
|
|
||||||
use serde::{de::IgnoredAny, Deserialize, Serialize, Serializer};
|
|
||||||
use serde_json::value::RawValue as RawJsonValue;
|
|
||||||
|
|
||||||
use self::room::redaction::SyncRoomRedactionEvent;
|
use self::room::redaction::SyncRoomRedactionEvent;
|
||||||
use crate::{serde::Raw, EventEncryptionAlgorithm, RoomVersionId};
|
use crate::{EventEncryptionAlgorithm, RoomVersionId};
|
||||||
|
|
||||||
// Needs to be public for trybuild tests
|
// Needs to be public for trybuild tests
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod _custom;
|
pub mod _custom;
|
||||||
|
mod content;
|
||||||
mod enums;
|
mod enums;
|
||||||
mod event_kinds;
|
mod event_kinds;
|
||||||
mod unsigned;
|
mod unsigned;
|
||||||
@ -193,26 +191,12 @@ pub mod voice;
|
|||||||
#[cfg(feature = "unstable-msc2675")]
|
#[cfg(feature = "unstable-msc2675")]
|
||||||
pub use self::relation::Relations;
|
pub use self::relation::Relations;
|
||||||
pub use self::{
|
pub use self::{
|
||||||
|
content::*,
|
||||||
enums::*,
|
enums::*,
|
||||||
event_kinds::*,
|
event_kinds::*,
|
||||||
unsigned::{MessageLikeUnsigned, RedactedUnsigned, StateUnsigned},
|
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<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait to define the behavior of redacting an event.
|
/// Trait to define the behavior of redacting an event.
|
||||||
pub trait Redact {
|
pub trait Redact {
|
||||||
/// The redacted form of the event.
|
/// The redacted form of the event.
|
||||||
@ -239,118 +223,6 @@ pub trait RedactContent {
|
|||||||
fn redact(self, version: &RoomVersionId) -> Self::Redacted;
|
fn redact(self, version: &RoomVersionId) -> Self::Redacted;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Raw<T>
|
|
||||||
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> {
|
|
||||||
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<Self> {
|
|
||||||
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`.
|
/// Helper struct to determine the event kind from a `serde_json::value::RawValue`.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
133
crates/ruma-common/src/events/content.rs
Normal file
133
crates/ruma-common/src/events/content.rs
Normal file
@ -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<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Raw<T>
|
||||||
|
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> {
|
||||||
|
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<Self> {
|
||||||
|
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,
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user