Skip to main content

m4a_matrix_core/
pdu.rs

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/// A persistent data unit with the fields state resolution and the auth rules read.
7#[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    /// Reads a wire-format PDU (no `event_id` inside; the caller computed it).
25    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}