1use ruma_common::{CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId};
2use ruma_events::TimelineEventType;
3use ruma_state_res::events::Event;
4use serde_json::value::RawValue;
5
6#[derive(Clone, Debug)]
8pub struct Pdu {
9 pub event_id: OwnedEventId,
10 pub room_id: OwnedRoomId,
11 pub sender: OwnedUserId,
12 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
13 pub kind: TimelineEventType,
14 pub content: Box<RawValue>,
15 pub state_key: Option<String>,
16 pub prev_events: Vec<OwnedEventId>,
17 pub auth_events: Vec<OwnedEventId>,
18 pub depth: u64,
19 pub redacts: Option<OwnedEventId>,
20 pub rejected: bool,
21}
22
23impl Pdu {
24 pub fn from_wire(event_id: OwnedEventId, obj: &CanonicalJsonObject) -> Result<Self, String> {
26 let v = serde_json::to_value(obj).map_err(|e| e.to_string())?;
27 let s = |k: &str| v.get(k).and_then(|x| x.as_str()).map(str::to_owned);
28 let ids = |k: &str| -> Result<Vec<OwnedEventId>, String> {
29 v.get(k)
30 .and_then(|x| x.as_array())
31 .map(|a| a.iter().map(|e| e.as_str().ok_or("event id".to_string()).and_then(|e| EventId::parse(e).map_err(|e| e.to_string()))).collect())
32 .unwrap_or_else(|| Ok(vec![]))
33 };
34 Ok(Self {
35 event_id,
36 room_id: RoomId::parse(s("room_id").ok_or("room_id")?).map_err(|e| e.to_string())?,
37 sender: UserId::parse(s("sender").ok_or("sender")?).map_err(|e| e.to_string())?,
38 origin_server_ts: MilliSecondsSinceUnixEpoch(
39 js_int::UInt::try_from(v.get("origin_server_ts").and_then(|x| x.as_u64()).ok_or("origin_server_ts")?).map_err(|e| e.to_string())?,
40 ),
41 kind: TimelineEventType::from(s("type").ok_or("type")?),
42 content: RawValue::from_string(v.get("content").ok_or("content")?.to_string()).map_err(|e| e.to_string())?,
43 state_key: s("state_key"),
44 prev_events: ids("prev_events")?,
45 auth_events: ids("auth_events")?,
46 depth: v.get("depth").and_then(|x| x.as_u64()).unwrap_or(0),
47 redacts: None,
48 rejected: false,
49 })
50 }
51}
52
53impl Event for Pdu {
54 type Id = OwnedEventId;
55 fn event_id(&self) -> &Self::Id {
56 &self.event_id
57 }
58 fn room_id(&self) -> Option<&RoomId> {
59 Some(&self.room_id)
60 }
61 fn sender(&self) -> &UserId {
62 &self.sender
63 }
64 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
65 self.origin_server_ts
66 }
67 fn event_type(&self) -> &TimelineEventType {
68 &self.kind
69 }
70 fn content(&self) -> &RawValue {
71 &self.content
72 }
73 fn state_key(&self) -> Option<&str> {
74 self.state_key.as_deref()
75 }
76 fn prev_events(&self) -> Box<dyn DoubleEndedIterator<Item = &Self::Id> + '_> {
77 Box::new(self.prev_events.iter())
78 }
79 fn auth_events(&self) -> Box<dyn DoubleEndedIterator<Item = &Self::Id> + '_> {
80 Box::new(self.auth_events.iter())
81 }
82 fn redacts(&self) -> Option<&Self::Id> {
83 self.redacts.as_ref()
84 }
85 fn rejected(&self) -> bool {
86 self.rejected
87 }
88}