1use ruma::{
17 EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId,
18 events::TimelineEventType, state_res::Event as StateResEvent,
19};
20use serde::{Serialize, Serializer};
21use serde_json::value::RawValue as RawJsonValue;
22
23use crate::types::HashedEventRef;
24
25pub type ClientEvent = Box<RawJsonValue>;
27
28trait AsEventId {
30 fn as_event_id(&self) -> &OwnedEventId;
32}
33
34impl AsEventId for OwnedEventId {
35 fn as_event_id(&self) -> &OwnedEventId {
36 self
37 }
38}
39
40impl AsEventId for HashedEventRef {
41 fn as_event_id(&self) -> &OwnedEventId {
42 &self.event_id
43 }
44}
45
46#[derive(Debug, Clone)]
48pub struct PduCommon {
49 pub(crate) event_id: OwnedEventId,
51 pub(crate) room_id: OwnedRoomId,
53 pub(crate) sender: OwnedUserId,
55 pub(crate) event_type: TimelineEventType,
57 pub(crate) content: Box<RawJsonValue>,
59 pub(crate) state_key: Option<String>,
61 pub(crate) origin_server_ts: MilliSecondsSinceUnixEpoch,
63 pub(crate) redacts: Option<OwnedEventId>,
65 pub(crate) rejected: bool,
67 pub(crate) raw: Box<RawJsonValue>,
69}
70
71impl PduCommon {
72 #[must_use]
74 pub fn event_id(&self) -> &EventId {
75 &self.event_id
76 }
77
78 #[must_use]
80 pub fn room_id(&self) -> &RoomId {
81 &self.room_id
82 }
83
84 #[must_use]
86 pub fn sender(&self) -> &UserId {
87 &self.sender
88 }
89
90 #[must_use]
92 pub const fn event_type(&self) -> &TimelineEventType {
93 &self.event_type
94 }
95
96 #[must_use]
98 pub fn content(&self) -> &RawJsonValue {
99 &self.content
100 }
101
102 #[must_use]
104 pub fn state_key(&self) -> Option<&str> {
105 self.state_key.as_deref()
106 }
107
108 #[must_use]
110 pub const fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
111 self.origin_server_ts
112 }
113
114 #[must_use]
116 pub fn redacts(&self) -> Option<&EventId> {
117 self.redacts.as_deref()
118 }
119
120 #[must_use]
122 pub const fn rejected(&self) -> bool {
123 self.rejected
124 }
125
126 #[must_use]
128 pub fn raw(&self) -> &RawJsonValue {
129 &self.raw
130 }
131}
132
133#[derive(Debug, Clone)]
135pub struct V1Pdu {
136 pub common: PduCommon,
138 pub prev_events: Vec<OwnedEventId>,
140 pub auth_events: Vec<OwnedEventId>,
142 pub depth: u64,
144}
145
146#[derive(Debug, Clone)]
148pub struct V3Pdu {
149 pub common: PduCommon,
151 pub prev_events: Vec<OwnedEventId>,
153 pub auth_events: Vec<OwnedEventId>,
155 pub depth: u64,
157}
158
159#[derive(Debug, Clone)]
161pub struct V6Pdu {
162 pub common: PduCommon,
164 pub prev_events: Vec<OwnedEventId>,
166 pub auth_events: Vec<OwnedEventId>,
168 pub depth: u64,
170}
171
172#[derive(Debug, Clone)]
174pub struct V12Pdu {
175 pub common: PduCommon,
177 pub prev_events: Vec<OwnedEventId>,
179 pub auth_events: Vec<OwnedEventId>,
181 pub depth: u64,
183}
184
185#[derive(Debug, Clone)]
187pub enum Pdu {
188 V1(V1Pdu),
190 V3(V3Pdu),
192 V6(V6Pdu),
194 V12(V12Pdu),
196}
197
198macro_rules! impl_state_res_event {
200 ($pdu_type:ty) => {
201 impl StateResEvent for $pdu_type {
202 type Id = OwnedEventId;
203 fn event_id(&self) -> &Self::Id {
204 &self.common.event_id
205 }
206 fn room_id(&self) -> Option<&ruma::RoomId> {
207 Some(&self.common.room_id)
208 }
209 fn sender(&self) -> &ruma::UserId {
210 &self.common.sender
211 }
212 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
213 self.common.origin_server_ts
214 }
215 fn event_type(&self) -> &ruma::events::TimelineEventType {
216 &self.common.event_type
217 }
218 fn content(&self) -> &RawJsonValue {
219 self.common.content.as_ref()
220 }
221 fn state_key(&self) -> Option<&str> {
222 self.common.state_key.as_deref()
223 }
224 fn prev_events(&self) -> Box<dyn DoubleEndedIterator<Item = &Self::Id> + '_> {
225 Box::new(self.prev_events.iter().map(AsEventId::as_event_id))
226 }
227 fn auth_events(&self) -> Box<dyn DoubleEndedIterator<Item = &Self::Id> + '_> {
228 Box::new(self.auth_events.iter().map(AsEventId::as_event_id))
229 }
230 fn redacts(&self) -> Option<&Self::Id> {
231 self.common.redacts.as_ref()
232 }
233 fn rejected(&self) -> bool {
234 self.common.rejected
235 }
236 }
237 };
238}
239
240impl_state_res_event!(V1Pdu);
241impl_state_res_event!(V3Pdu);
242impl_state_res_event!(V6Pdu);
243impl_state_res_event!(V12Pdu);
244
245impl StateResEvent for Pdu {
246 type Id = OwnedEventId;
247
248 fn event_id(&self) -> &Self::Id {
249 match self {
250 Self::V1(pdu) => pdu.event_id(),
251 Self::V3(pdu) => pdu.event_id(),
252 Self::V6(pdu) => pdu.event_id(),
253 Self::V12(pdu) => pdu.event_id(),
254 }
255 }
256
257 fn room_id(&self) -> Option<&RoomId> {
258 match self {
259 Self::V1(pdu) => pdu.room_id(),
260 Self::V3(pdu) => pdu.room_id(),
261 Self::V6(pdu) => pdu.room_id(),
262 Self::V12(pdu) => pdu.room_id(),
263 }
264 }
265
266 fn sender(&self) -> &UserId {
267 match self {
268 Self::V1(pdu) => pdu.sender(),
269 Self::V3(pdu) => pdu.sender(),
270 Self::V6(pdu) => pdu.sender(),
271 Self::V12(pdu) => pdu.sender(),
272 }
273 }
274
275 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
276 match self {
277 Self::V1(pdu) => pdu.origin_server_ts(),
278 Self::V3(pdu) => pdu.origin_server_ts(),
279 Self::V6(pdu) => pdu.origin_server_ts(),
280 Self::V12(pdu) => pdu.origin_server_ts(),
281 }
282 }
283
284 fn event_type(&self) -> &TimelineEventType {
285 match self {
286 Self::V1(pdu) => pdu.event_type(),
287 Self::V3(pdu) => pdu.event_type(),
288 Self::V6(pdu) => pdu.event_type(),
289 Self::V12(pdu) => pdu.event_type(),
290 }
291 }
292
293 fn content(&self) -> &RawJsonValue {
294 match self {
295 Self::V1(pdu) => pdu.content(),
296 Self::V3(pdu) => pdu.content(),
297 Self::V6(pdu) => pdu.content(),
298 Self::V12(pdu) => pdu.content(),
299 }
300 }
301
302 fn state_key(&self) -> Option<&str> {
303 match self {
304 Self::V1(pdu) => pdu.state_key(),
305 Self::V3(pdu) => pdu.state_key(),
306 Self::V6(pdu) => pdu.state_key(),
307 Self::V12(pdu) => pdu.state_key(),
308 }
309 }
310
311 fn prev_events(&self) -> Box<dyn DoubleEndedIterator<Item = &Self::Id> + '_> {
312 match self {
313 Self::V1(pdu) => pdu.prev_events(),
314 Self::V3(pdu) => pdu.prev_events(),
315 Self::V6(pdu) => pdu.prev_events(),
316 Self::V12(pdu) => pdu.prev_events(),
317 }
318 }
319
320 fn auth_events(&self) -> Box<dyn DoubleEndedIterator<Item = &Self::Id> + '_> {
321 match self {
322 Self::V1(pdu) => pdu.auth_events(),
323 Self::V3(pdu) => pdu.auth_events(),
324 Self::V6(pdu) => pdu.auth_events(),
325 Self::V12(pdu) => pdu.auth_events(),
326 }
327 }
328
329 fn redacts(&self) -> Option<&Self::Id> {
330 match self {
331 Self::V1(pdu) => pdu.redacts(),
332 Self::V3(pdu) => pdu.redacts(),
333 Self::V6(pdu) => pdu.redacts(),
334 Self::V12(pdu) => pdu.redacts(),
335 }
336 }
337
338 fn rejected(&self) -> bool {
339 match self {
340 Self::V1(pdu) => pdu.rejected(),
341 Self::V3(pdu) => pdu.rejected(),
342 Self::V6(pdu) => pdu.rejected(),
343 Self::V12(pdu) => pdu.rejected(),
344 }
345 }
346}
347
348impl Serialize for Pdu {
350 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
351 self.raw().serialize(serializer)
352 }
353}
354
355impl Pdu {
356 #[must_use]
358 pub fn raw(&self) -> &serde_json::value::RawValue {
359 match self {
360 Pdu::V1(pdu) => &pdu.common.raw,
361 Pdu::V3(pdu) => &pdu.common.raw,
362 Pdu::V6(pdu) => &pdu.common.raw,
363 Pdu::V12(pdu) => &pdu.common.raw,
364 }
365 }
366
367 #[must_use]
369 pub fn depth(&self) -> u64 {
370 match self {
371 Pdu::V1(pdu) => pdu.depth,
372 Pdu::V3(pdu) => pdu.depth,
373 Pdu::V6(pdu) => pdu.depth,
374 Pdu::V12(pdu) => pdu.depth,
375 }
376 }
377
378 #[expect(
380 clippy::same_name_method,
381 reason = " Duplicates `state_res::Pdu`. But we don't want other crates to include `state_res` "
382 )]
383 #[must_use]
384 pub fn event_id(&self) -> &EventId {
385 match self {
386 Pdu::V1(pdu) => pdu.event_id(),
387 Pdu::V3(pdu) => pdu.event_id(),
388 Pdu::V6(pdu) => pdu.event_id(),
389 Pdu::V12(pdu) => pdu.event_id(),
390 }
391 }
392}
393
394mod tests;