1mod builder;
8mod count;
9mod format;
10mod hashes;
11mod id;
12mod raw_id;
13#[cfg(test)]
14mod tests;
15mod unsigned;
16
17use std::cmp::Ordering;
18
19use ruma::{
20 CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId,
21 OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, UInt, UserId,
22 canonical_json::redact_in_place,
23 events::TimelineEventType,
24 room_version_rules::{RedactionRules, RoomVersionRules},
25 serde::Raw,
26};
27use serde::{Deserialize, Serialize};
28use serde_json::value::RawValue as RawJsonValue;
29use smallvec::SmallVec;
30
31pub use self::{
32 Count as PduCount, Id as PduId, Pdu as PduEvent, RawId as RawPduId,
33 builder::{Builder, Builder as PduBuilder},
34 count::Count,
35 format::{
36 check::{check_room_id, check_rules},
37 from_incoming_federation, into_outgoing_federation,
38 },
39 hashes::EventHashes as EventHash,
40 id::Id,
41 raw_id::*,
42};
43use super::{Event, ShortRoomId, StateKey};
44use crate::{Result, err};
45
46#[derive(Clone, Deserialize, Serialize, Debug)]
52pub struct Pdu {
53 #[serde(rename = "type")]
57 pub kind: TimelineEventType,
58
59 pub content: Content,
63
64 pub event_id: OwnedEventId,
69
70 pub room_id: OwnedRoomId,
75
76 pub sender: OwnedUserId,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
87 pub state_key: Option<StateKey>,
88
89 #[serde(skip_serializing_if = "Option::is_none")]
94 pub redacts: Option<OwnedEventId>,
95
96 pub prev_events: PrevEvents,
100
101 pub auth_events: AuthEvents,
106
107 pub origin_server_ts: UInt,
111
112 pub depth: UInt,
117
118 pub hashes: EventHash,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
129 pub origin: Option<OwnedServerName>,
130
131 #[serde(default, skip_serializing_if = "Option::is_none")]
136 pub unsigned: Option<Unsigned>,
137
138 #[cfg(test)]
143 #[serde(default, skip_serializing)]
144 pub rejected: bool,
145}
146
147pub type PrevEvents = SmallVec<[OwnedEventId; 1]>;
152
153pub type AuthEvents = SmallVec<[OwnedEventId; 3]>;
158
159pub type Content = Raw<CanonicalJsonObject, 112>;
164
165pub type Unsigned = Raw<CanonicalJsonObject, 112>;
172
173pub const MAX_PDU_BYTES: usize = 65_535;
176
177pub const MAX_PREV_EVENTS: usize = 20;
180
181pub const MAX_AUTH_EVENTS: usize = 10;
184
185impl Pdu {
186 pub fn from_object_and_roomid_and_eventid(
191 room_id: &RoomId,
192 event_id: &EventId,
193 mut json: CanonicalJsonObject,
194 ) -> Result<Self> {
195 let room_id = CanonicalJsonValue::String(room_id.into());
196 json.insert("room_id".into(), room_id);
197 Self::from_object_and_eventid(event_id, json)
198 }
199
200 pub fn from_object_and_eventid(
205 event_id: &EventId,
206 mut json: CanonicalJsonObject,
207 ) -> Result<Self> {
208 let event_id = CanonicalJsonValue::String(event_id.into());
209 json.insert("event_id".into(), event_id);
210 Self::from_object(json)
211 }
212
213 pub fn from_object_federation(
224 room_id: &RoomId,
225 event_id: &EventId,
226 json: CanonicalJsonObject,
227 rules: &RoomVersionRules,
228 ) -> Result<(Self, CanonicalJsonObject)> {
229 let json = from_incoming_federation(room_id, event_id, json, rules);
230 let pdu = Self::from_object_checked(json.clone(), rules)?;
231 check_room_id(&pdu, room_id)?;
232 Ok((pdu, json))
233 }
234
235 pub fn from_object_checked(
240 json: CanonicalJsonObject,
241 rules: &RoomVersionRules,
242 ) -> Result<Self> {
243 check_rules(&json, &rules.event_format)?;
244 Self::from_object(json)
245 }
246
247 pub fn from_object(json: CanonicalJsonObject) -> Result<Self> {
252 let json = CanonicalJsonValue::Object(json);
253 Self::from_value(json)
254 }
255
256 pub fn from_raw_value(json: &RawJsonValue) -> Result<Self> {
267 let json: CanonicalJsonValue = json.into();
268 Self::from_value(json)
269 }
270
271 pub fn from_value(json: CanonicalJsonValue) -> Result<Self> {
276 serde_json::from_value(json.into()).map_err(Into::into)
277 }
278
279 pub fn from_raw_json(json: &RawJsonValue) -> Result<Self> {
285 Self::deserialize(json).map_err(Into::into)
286 }
287
288 pub fn redacted(&self, rules: &RedactionRules) -> Result<Self> {
292 let mut object = self.to_canonical_object();
293
294 redact_in_place(&mut object, rules, None)
295 .map_err(|e| err!("Failed to redact event: {e}"))?;
296
297 Self::from_object(object)
298 }
299}
300
301impl Event for Pdu
302where
303 Self: Send + Sync + 'static,
304{
305 #[inline]
306 fn auth_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
307 self.auth_events.iter().map(AsRef::as_ref)
308 }
309
310 #[inline]
311 fn auth_events_into(
312 self,
313 ) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + Send {
314 self.auth_events.into_iter()
315 }
316
317 #[inline]
318 fn content(&self) -> &RawJsonValue { self.content.json() }
319
320 #[inline]
321 fn event_id(&self) -> &EventId { &self.event_id }
322
323 #[inline]
324 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
325 MilliSecondsSinceUnixEpoch(self.origin_server_ts)
326 }
327
328 #[inline]
329 fn prev_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
330 self.prev_events.iter().map(AsRef::as_ref)
331 }
332
333 #[inline]
334 fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() }
335
336 #[cfg(test)]
337 #[inline]
338 fn rejected(&self) -> bool { self.rejected }
339
340 #[cfg(not(test))]
341 #[inline]
342 fn rejected(&self) -> bool { false }
343
344 #[inline]
345 fn room_id(&self) -> &RoomId { &self.room_id }
346
347 #[inline]
348 fn sender(&self) -> &UserId { &self.sender }
349
350 #[inline]
351 fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
352
353 #[inline]
354 fn kind(&self) -> &TimelineEventType { &self.kind }
355
356 #[inline]
357 fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_ref().map(Unsigned::json) }
358
359 #[inline]
360 fn as_mut_pdu(&mut self) -> &mut Pdu { self }
361
362 #[inline]
363 fn as_pdu(&self) -> &Pdu { self }
364
365 #[inline]
366 fn into_pdu(self) -> Pdu { self }
367
368 #[inline]
369 fn is_owned(&self) -> bool { true }
370}
371
372impl Event for &Pdu
373where
374 Self: Send,
375{
376 #[inline]
377 fn auth_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
378 self.auth_events.iter().map(AsRef::as_ref)
379 }
380
381 #[inline]
382 fn auth_events_into(
383 self,
384 ) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + Send {
385 self.auth_events.iter().map(ToOwned::to_owned)
386 }
387
388 #[inline]
389 fn content(&self) -> &RawJsonValue { self.content.json() }
390
391 #[inline]
392 fn event_id(&self) -> &EventId { &self.event_id }
393
394 #[inline]
395 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
396 MilliSecondsSinceUnixEpoch(self.origin_server_ts)
397 }
398
399 #[inline]
400 fn prev_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
401 self.prev_events.iter().map(AsRef::as_ref)
402 }
403
404 #[inline]
405 fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() }
406
407 #[cfg(test)]
408 #[inline]
409 fn rejected(&self) -> bool { self.rejected }
410
411 #[cfg(not(test))]
412 #[inline]
413 fn rejected(&self) -> bool { false }
414
415 #[inline]
416 fn room_id(&self) -> &RoomId { &self.room_id }
417
418 #[inline]
419 fn sender(&self) -> &UserId { &self.sender }
420
421 #[inline]
422 fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
423
424 #[inline]
425 fn kind(&self) -> &TimelineEventType { &self.kind }
426
427 #[inline]
428 fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_ref().map(Unsigned::json) }
429
430 #[inline]
431 fn as_pdu(&self) -> &Pdu { self }
432
433 #[inline]
434 fn into_pdu(self) -> Pdu { self.clone() }
435
436 #[inline]
437 fn is_owned(&self) -> bool { false }
438}
439
440impl Eq for Pdu {}
442
443impl PartialEq for Pdu {
445 fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id }
446}
447
448impl Ord for Pdu {
450 fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) }
451}
452
453impl PartialOrd for Pdu {
455 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
456}