tuwunel_core/matrix/
pdu.rs1mod builder;
2mod count;
3mod format;
4mod hashes;
5mod id;
6mod raw_id;
7#[cfg(test)]
8mod tests;
9mod unsigned;
10
11use std::cmp::Ordering;
12
13use ruma::{
14 CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId,
15 OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, UInt, UserId, events::TimelineEventType,
16 room_version_rules::RoomVersionRules, serde::Raw,
17};
18use serde::{Deserialize, Serialize};
19use serde_json::value::RawValue as RawJsonValue;
20use smallvec::SmallVec;
21
22pub use self::{
23 Count as PduCount, Id as PduId, Pdu as PduEvent, RawId as RawPduId,
24 builder::{Builder, Builder as PduBuilder},
25 count::Count,
26 format::{
27 check::{check_room_id, check_rules},
28 from_incoming_federation, into_outgoing_federation,
29 },
30 hashes::EventHashes as EventHash,
31 id::Id,
32 raw_id::*,
33};
34use super::{Event, ShortRoomId, StateKey};
35use crate::Result;
36
37#[derive(Clone, Deserialize, Serialize, Debug)]
39pub struct Pdu {
40 #[serde(rename = "type")]
41 pub kind: TimelineEventType,
42
43 pub content: Content,
44
45 pub event_id: OwnedEventId,
46
47 pub room_id: OwnedRoomId,
48
49 pub sender: OwnedUserId,
50
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub state_key: Option<StateKey>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub redacts: Option<OwnedEventId>,
56
57 pub prev_events: PrevEvents,
58
59 pub auth_events: AuthEvents,
60
61 pub origin_server_ts: UInt,
62
63 pub depth: UInt,
64
65 pub hashes: EventHash,
66
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub origin: Option<OwnedServerName>,
69
70 #[serde(default, skip_serializing_if = "Option::is_none")]
71 pub unsigned: Option<Unsigned>,
72
73 #[cfg(test)]
75 #[serde(default, skip_serializing)]
76 pub rejected: bool,
77}
78
79pub type PrevEvents = SmallVec<[OwnedEventId; 1]>;
83
84pub type AuthEvents = SmallVec<[OwnedEventId; 3]>;
88
89pub type Content = Raw<CanonicalJsonObject, 112>;
93
94pub type Unsigned = Raw<CanonicalJsonObject, 112>;
99
100pub const MAX_PDU_BYTES: usize = 65_535;
103
104pub const MAX_PREV_EVENTS: usize = 20;
107
108pub const MAX_AUTH_EVENTS: usize = 10;
111
112impl Pdu {
113 pub fn from_object_and_roomid_and_eventid(
114 room_id: &RoomId,
115 event_id: &EventId,
116 mut json: CanonicalJsonObject,
117 ) -> Result<Self> {
118 let room_id = CanonicalJsonValue::String(room_id.into());
119 json.insert("room_id".into(), room_id);
120 Self::from_object_and_eventid(event_id, json)
121 }
122
123 pub fn from_object_and_eventid(
124 event_id: &EventId,
125 mut json: CanonicalJsonObject,
126 ) -> Result<Self> {
127 let event_id = CanonicalJsonValue::String(event_id.into());
128 json.insert("event_id".into(), event_id);
129 Self::from_object(json)
130 }
131
132 pub fn from_object_federation(
133 room_id: &RoomId,
134 event_id: &EventId,
135 json: CanonicalJsonObject,
136 rules: &RoomVersionRules,
137 ) -> Result<(Self, CanonicalJsonObject)> {
138 let json = from_incoming_federation(room_id, event_id, json, rules);
139 let pdu = Self::from_object_checked(json.clone(), rules)?;
140 check_room_id(&pdu, room_id)?;
141 Ok((pdu, json))
142 }
143
144 pub fn from_object_checked(
145 json: CanonicalJsonObject,
146 rules: &RoomVersionRules,
147 ) -> Result<Self> {
148 check_rules(&json, &rules.event_format)?;
149 Self::from_object(json)
150 }
151
152 pub fn from_object(json: CanonicalJsonObject) -> Result<Self> {
153 let json = CanonicalJsonValue::Object(json);
154 Self::from_value(json)
155 }
156
157 pub fn from_raw_value(json: &RawJsonValue) -> Result<Self> {
158 let json: CanonicalJsonValue = json.into();
159 Self::from_value(json)
160 }
161
162 pub fn from_value(json: CanonicalJsonValue) -> Result<Self> {
163 serde_json::from_value(json.into()).map_err(Into::into)
164 }
165
166 pub fn from_raw_json(json: &RawJsonValue) -> Result<Self> {
167 Self::deserialize(json).map_err(Into::into)
168 }
169}
170
171impl Event for Pdu
172where
173 Self: Send + Sync + 'static,
174{
175 #[inline]
176 fn auth_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
177 self.auth_events.iter().map(AsRef::as_ref)
178 }
179
180 #[inline]
181 fn auth_events_into(
182 self,
183 ) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + Send {
184 self.auth_events.into_iter()
185 }
186
187 #[inline]
188 fn content(&self) -> &RawJsonValue { self.content.json() }
189
190 #[inline]
191 fn event_id(&self) -> &EventId { &self.event_id }
192
193 #[inline]
194 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
195 MilliSecondsSinceUnixEpoch(self.origin_server_ts)
196 }
197
198 #[inline]
199 fn prev_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
200 self.prev_events.iter().map(AsRef::as_ref)
201 }
202
203 #[inline]
204 fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() }
205
206 #[cfg(test)]
207 #[inline]
208 fn rejected(&self) -> bool { self.rejected }
209
210 #[cfg(not(test))]
211 #[inline]
212 fn rejected(&self) -> bool { false }
213
214 #[inline]
215 fn room_id(&self) -> &RoomId { &self.room_id }
216
217 #[inline]
218 fn sender(&self) -> &UserId { &self.sender }
219
220 #[inline]
221 fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
222
223 #[inline]
224 fn kind(&self) -> &TimelineEventType { &self.kind }
225
226 #[inline]
227 fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_ref().map(Unsigned::json) }
228
229 #[inline]
230 fn as_mut_pdu(&mut self) -> &mut Pdu { self }
231
232 #[inline]
233 fn as_pdu(&self) -> &Pdu { self }
234
235 #[inline]
236 fn into_pdu(self) -> Pdu { self }
237
238 #[inline]
239 fn is_owned(&self) -> bool { true }
240}
241
242impl Event for &Pdu
243where
244 Self: Send,
245{
246 #[inline]
247 fn auth_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
248 self.auth_events.iter().map(AsRef::as_ref)
249 }
250
251 #[inline]
252 fn auth_events_into(
253 self,
254 ) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + Send {
255 self.auth_events.iter().map(ToOwned::to_owned)
256 }
257
258 #[inline]
259 fn content(&self) -> &RawJsonValue { self.content.json() }
260
261 #[inline]
262 fn event_id(&self) -> &EventId { &self.event_id }
263
264 #[inline]
265 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
266 MilliSecondsSinceUnixEpoch(self.origin_server_ts)
267 }
268
269 #[inline]
270 fn prev_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
271 self.prev_events.iter().map(AsRef::as_ref)
272 }
273
274 #[inline]
275 fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() }
276
277 #[cfg(test)]
278 #[inline]
279 fn rejected(&self) -> bool { self.rejected }
280
281 #[cfg(not(test))]
282 #[inline]
283 fn rejected(&self) -> bool { false }
284
285 #[inline]
286 fn room_id(&self) -> &RoomId { &self.room_id }
287
288 #[inline]
289 fn sender(&self) -> &UserId { &self.sender }
290
291 #[inline]
292 fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
293
294 #[inline]
295 fn kind(&self) -> &TimelineEventType { &self.kind }
296
297 #[inline]
298 fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_ref().map(Unsigned::json) }
299
300 #[inline]
301 fn as_pdu(&self) -> &Pdu { self }
302
303 #[inline]
304 fn into_pdu(self) -> Pdu { self.clone() }
305
306 #[inline]
307 fn is_owned(&self) -> bool { false }
308}
309
310impl Eq for Pdu {}
312
313impl PartialEq for Pdu {
315 fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id }
316}
317
318impl Ord for Pdu {
320 fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) }
321}
322
323impl PartialOrd for Pdu {
325 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
326}