ruma_events/
content.rs

1use std::fmt;
2
3use ruma_common::serde::{CanBeEmpty, Raw};
4use serde::{de::DeserializeOwned, Serialize};
5use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};
6
7use super::{
8    EphemeralRoomEventType, GlobalAccountDataEventType, MessageLikeEventType,
9    RoomAccountDataEventType, StateEventType, ToDeviceEventType,
10};
11
12/// The base trait that all event content types implement.
13///
14/// Use [`macros::EventContent`] to derive this traits. It is not meant to be implemented manually.
15///
16/// [`macros::EventContent`]: super::macros::EventContent
17pub trait EventContent: Sized + Serialize {
18    /// The Rust enum for the event kind's known types.
19    type EventType;
20
21    /// Get the event's type, like `m.room.message`.
22    fn event_type(&self) -> Self::EventType;
23}
24
25/// Extension trait for [`Raw<T>`].
26pub trait RawExt<T: EventContentFromType> {
27    /// Try to deserialize the JSON as an event's content with the given event type.
28    fn deserialize_with_type(&self, event_type: T::EventType) -> serde_json::Result<T>;
29}
30
31impl<T> RawExt<T> for Raw<T>
32where
33    T: EventContentFromType,
34    T::EventType: fmt::Display,
35{
36    fn deserialize_with_type(&self, event_type: T::EventType) -> serde_json::Result<T> {
37        T::from_parts(&event_type.to_string(), self.json())
38    }
39}
40
41/// An event content type with a statically-known event `type` value.
42pub trait StaticEventContent: EventContent {
43    /// The event type.
44    const TYPE: &'static str;
45}
46
47/// Content of a global account-data event.
48pub trait GlobalAccountDataEventContent:
49    EventContent<EventType = GlobalAccountDataEventType>
50{
51}
52
53/// Content of a room-specific account-data event.
54pub trait RoomAccountDataEventContent: EventContent<EventType = RoomAccountDataEventType> {}
55
56/// Content of an ephemeral room event.
57pub trait EphemeralRoomEventContent: EventContent<EventType = EphemeralRoomEventType> {}
58
59/// Content of a non-redacted message-like event.
60pub trait MessageLikeEventContent: EventContent<EventType = MessageLikeEventType> {}
61
62/// Content of a redacted message-like event.
63pub trait RedactedMessageLikeEventContent: EventContent<EventType = MessageLikeEventType> {}
64
65/// Content of a non-redacted state event.
66pub trait StateEventContent: EventContent<EventType = StateEventType> {
67    /// The type of the event's `state_key` field.
68    type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
69}
70
71/// Content of a non-redacted state event with a corresponding possibly-redacted type.
72pub trait StaticStateEventContent: StateEventContent {
73    /// The possibly redacted form of the event's content.
74    type PossiblyRedacted: PossiblyRedactedStateEventContent;
75
76    /// The type of the event's `unsigned` field.
77    type Unsigned: Clone + fmt::Debug + Default + CanBeEmpty + DeserializeOwned;
78}
79
80/// Content of a redacted state event.
81pub trait RedactedStateEventContent: EventContent<EventType = StateEventType> {
82    /// The type of the event's `state_key` field.
83    type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
84}
85
86/// Content of a state event.
87pub trait PossiblyRedactedStateEventContent: EventContent<EventType = StateEventType> {
88    /// The type of the event's `state_key` field.
89    type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
90}
91
92/// Content of a to-device event.
93pub trait ToDeviceEventContent: EventContent<EventType = ToDeviceEventType> {}
94
95/// Event content that can be deserialized with its event type.
96pub trait EventContentFromType: EventContent {
97    /// Constructs this event content from the given event type and JSON.
98    fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self>;
99}
100
101impl<T> EventContentFromType for T
102where
103    T: EventContent + DeserializeOwned,
104{
105    fn from_parts(_event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
106        from_json_str(content.get())
107    }
108}