1use ruma::{
16 events::{
17 EventContent, EventContentFromType, MessageLikeEventContent, MessageLikeEventType,
18 MessageLikeUnsigned, OriginalSyncMessageLikeEvent, OriginalSyncStateEvent,
19 PossiblyRedactedStateEventContent, RedactContent, RedactedMessageLikeEventContent,
20 RedactedStateEventContent, RedactedSyncMessageLikeEvent, RedactedSyncStateEvent,
21 StateEventContent, StateEventType, StaticStateEventContent, TimelineEventType,
22 },
23 serde::from_raw_json_value,
24 EventId, MilliSecondsSinceUnixEpoch, TransactionId, UserId,
25};
26use serde::{de, Deserialize, Serialize};
27use serde_json::value::RawValue as RawJsonValue;
28
29#[allow(clippy::large_enum_variant)]
30pub(crate) enum SyncTimelineEventWithoutContent {
31 OriginalMessageLike(OriginalSyncMessageLikeEvent<NoMessageLikeEventContent>),
32 RedactedMessageLike(RedactedSyncMessageLikeEvent<NoMessageLikeEventContent>),
33 OriginalState(OriginalSyncStateEvent<NoStateEventContent>),
34 RedactedState(RedactedSyncStateEvent<NoStateEventContent>),
35}
36
37impl SyncTimelineEventWithoutContent {
38 pub(crate) fn event_id(&self) -> &EventId {
39 match self {
40 Self::OriginalMessageLike(ev) => &ev.event_id,
41 Self::RedactedMessageLike(ev) => &ev.event_id,
42 Self::OriginalState(ev) => &ev.event_id,
43 Self::RedactedState(ev) => &ev.event_id,
44 }
45 }
46
47 pub(crate) fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
48 match self {
49 SyncTimelineEventWithoutContent::OriginalMessageLike(ev) => ev.origin_server_ts,
50 SyncTimelineEventWithoutContent::RedactedMessageLike(ev) => ev.origin_server_ts,
51 SyncTimelineEventWithoutContent::OriginalState(ev) => ev.origin_server_ts,
52 SyncTimelineEventWithoutContent::RedactedState(ev) => ev.origin_server_ts,
53 }
54 }
55
56 pub(crate) fn sender(&self) -> &UserId {
57 match self {
58 Self::OriginalMessageLike(ev) => &ev.sender,
59 Self::RedactedMessageLike(ev) => &ev.sender,
60 Self::OriginalState(ev) => &ev.sender,
61 Self::RedactedState(ev) => &ev.sender,
62 }
63 }
64
65 pub(crate) fn transaction_id(&self) -> Option<&TransactionId> {
66 match self {
67 SyncTimelineEventWithoutContent::OriginalMessageLike(ev) => {
68 ev.unsigned.transaction_id.as_deref()
69 }
70 SyncTimelineEventWithoutContent::OriginalState(ev) => {
71 ev.unsigned.transaction_id.as_deref()
72 }
73 SyncTimelineEventWithoutContent::RedactedMessageLike(_)
74 | SyncTimelineEventWithoutContent::RedactedState(_) => None,
75 }
76 }
77
78 pub(crate) fn event_type(&self) -> TimelineEventType {
79 match self {
80 SyncTimelineEventWithoutContent::OriginalMessageLike(ev) => {
81 ev.content.event_type().into()
82 }
83 SyncTimelineEventWithoutContent::RedactedMessageLike(ev) => {
84 ev.content.event_type().into()
85 }
86 SyncTimelineEventWithoutContent::OriginalState(ev) => ev.content.event_type().into(),
87 SyncTimelineEventWithoutContent::RedactedState(ev) => ev.content.event_type().into(),
88 }
89 }
90}
91
92#[derive(Deserialize)]
93struct EventDeHelper {
94 state_key: Option<de::IgnoredAny>,
95 #[serde(default)]
96 unsigned: UnsignedDeHelper,
97}
98
99#[derive(Deserialize, Default)]
100struct UnsignedDeHelper {
101 redacted_because: Option<de::IgnoredAny>,
102}
103
104impl<'de> Deserialize<'de> for SyncTimelineEventWithoutContent {
105 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
106 where
107 D: de::Deserializer<'de>,
108 {
109 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
110 let EventDeHelper { state_key, unsigned } = from_raw_json_value(&json)?;
111
112 Ok(match (state_key.is_some(), unsigned.redacted_because.is_some()) {
113 (false, false) => Self::OriginalMessageLike(from_raw_json_value(&json)?),
114 (false, true) => Self::RedactedMessageLike(from_raw_json_value(&json)?),
115 (true, false) => Self::OriginalState(from_raw_json_value(&json)?),
116 (true, true) => Self::RedactedState(from_raw_json_value(&json)?),
117 })
118 }
119}
120
121#[derive(Clone, Debug, Serialize)]
122pub(crate) struct NoMessageLikeEventContent {
123 #[serde(skip)]
124 pub event_type: MessageLikeEventType,
125}
126
127impl EventContent for NoMessageLikeEventContent {
128 type EventType = MessageLikeEventType;
129
130 fn event_type(&self) -> Self::EventType {
131 self.event_type.clone()
132 }
133}
134impl EventContentFromType for NoMessageLikeEventContent {
135 fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
136 Ok(Self { event_type: event_type.into() })
137 }
138}
139impl MessageLikeEventContent for NoMessageLikeEventContent {}
140impl RedactedMessageLikeEventContent for NoMessageLikeEventContent {}
141
142#[derive(Clone, Debug, Serialize)]
143pub(crate) struct NoStateEventContent {
144 #[serde(skip)]
145 pub event_type: StateEventType,
146}
147
148impl EventContent for NoStateEventContent {
149 type EventType = StateEventType;
150
151 fn event_type(&self) -> Self::EventType {
152 self.event_type.clone()
153 }
154}
155impl EventContentFromType for NoStateEventContent {
156 fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
157 Ok(Self { event_type: event_type.into() })
158 }
159}
160impl RedactContent for NoStateEventContent {
161 type Redacted = Self;
162
163 fn redact(self, _version: &ruma::RoomVersionId) -> Self::Redacted {
164 self
165 }
166}
167impl StateEventContent for NoStateEventContent {
168 type StateKey = String;
169}
170impl StaticStateEventContent for NoStateEventContent {
171 type Unsigned = MessageLikeUnsigned<NoMessageLikeEventContent>;
175 type PossiblyRedacted = Self;
176}
177impl RedactedStateEventContent for NoStateEventContent {
178 type StateKey = String;
179}
180impl PossiblyRedactedStateEventContent for NoStateEventContent {
181 type StateKey = String;
182}