1use std::fmt;
23use ruma_common::serde::{CanBeEmpty, Raw};
4use serde::{de::DeserializeOwned, Serialize};
5use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};
67use super::{
8 EphemeralRoomEventType, GlobalAccountDataEventType, MessageLikeEventType,
9 RoomAccountDataEventType, StateEventType, ToDeviceEventType,
10};
1112/// 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.
19type EventType;
2021/// Get the event's type, like `m.room.message`.
22fn event_type(&self) -> Self::EventType;
23}
2425/// 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.
28fn deserialize_with_type(&self, event_type: T::EventType) -> serde_json::Result<T>;
29}
3031impl<T> RawExt<T> for Raw<T>
32where
33T: EventContentFromType,
34 T::EventType: fmt::Display,
35{
36fn deserialize_with_type(&self, event_type: T::EventType) -> serde_json::Result<T> {
37 T::from_parts(&event_type.to_string(), self.json())
38 }
39}
4041/// An event content type with a statically-known event `type` value.
42pub trait StaticEventContent: EventContent {
43/// The event type.
44const TYPE: &'static str;
45}
4647/// Content of a global account-data event.
48pub trait GlobalAccountDataEventContent:
49 EventContent<EventType = GlobalAccountDataEventType>
50{
51}
5253/// Content of a room-specific account-data event.
54pub trait RoomAccountDataEventContent: EventContent<EventType = RoomAccountDataEventType> {}
5556/// Content of an ephemeral room event.
57pub trait EphemeralRoomEventContent: EventContent<EventType = EphemeralRoomEventType> {}
5859/// Content of a non-redacted message-like event.
60pub trait MessageLikeEventContent: EventContent<EventType = MessageLikeEventType> {}
6162/// Content of a redacted message-like event.
63pub trait RedactedMessageLikeEventContent: EventContent<EventType = MessageLikeEventType> {}
6465/// Content of a non-redacted state event.
66pub trait StateEventContent: EventContent<EventType = StateEventType> {
67/// The type of the event's `state_key` field.
68type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
69}
7071/// 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.
74type PossiblyRedacted: PossiblyRedactedStateEventContent;
7576/// The type of the event's `unsigned` field.
77type Unsigned: Clone + fmt::Debug + Default + CanBeEmpty + DeserializeOwned;
78}
7980/// Content of a redacted state event.
81pub trait RedactedStateEventContent: EventContent<EventType = StateEventType> {
82/// The type of the event's `state_key` field.
83type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
84}
8586/// Content of a state event.
87pub trait PossiblyRedactedStateEventContent: EventContent<EventType = StateEventType> {
88/// The type of the event's `state_key` field.
89type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
90}
9192/// Content of a to-device event.
93pub trait ToDeviceEventContent: EventContent<EventType = ToDeviceEventType> {}
9495/// 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.
98fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self>;
99}
100101impl<T> EventContentFromType for T
102where
103T: EventContent + DeserializeOwned,
104{
105fn from_parts(_event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
106 from_json_str(content.get())
107 }
108}