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<Box<RawJsonValue>>,
72
73 #[serde(default, skip_serializing_if = "Option::is_none")]
75 pub signatures: Option<Box<RawJsonValue>>,
76
77 #[cfg(test)]
79 #[serde(default, skip_serializing)]
80 pub rejected: bool,
81}
82
83pub type PrevEvents = SmallVec<[OwnedEventId; 1]>;
87
88pub type AuthEvents = SmallVec<[OwnedEventId; 3]>;
92
93pub type Content = Raw<CanonicalJsonObject, 112>;
97
98pub const MAX_PDU_BYTES: usize = 65_535;
101
102pub const MAX_PREV_EVENTS: usize = 20;
105
106pub const MAX_AUTH_EVENTS: usize = 10;
109
110impl Pdu {
111 pub fn from_object_and_roomid_and_eventid(
112 room_id: &RoomId,
113 event_id: &EventId,
114 mut json: CanonicalJsonObject,
115 ) -> Result<Self> {
116 let room_id = CanonicalJsonValue::String(room_id.into());
117 json.insert("room_id".into(), room_id);
118 Self::from_object_and_eventid(event_id, json)
119 }
120
121 pub fn from_object_and_eventid(
122 event_id: &EventId,
123 mut json: CanonicalJsonObject,
124 ) -> Result<Self> {
125 let event_id = CanonicalJsonValue::String(event_id.into());
126 json.insert("event_id".into(), event_id);
127 Self::from_object(json)
128 }
129
130 pub fn from_object_federation(
131 room_id: &RoomId,
132 event_id: &EventId,
133 json: CanonicalJsonObject,
134 rules: &RoomVersionRules,
135 ) -> Result<(Self, CanonicalJsonObject)> {
136 let json = from_incoming_federation(room_id, event_id, json, rules);
137 let pdu = Self::from_object_checked(json.clone(), rules)?;
138 check_room_id(&pdu, room_id)?;
139 Ok((pdu, json))
140 }
141
142 pub fn from_object_checked(
143 json: CanonicalJsonObject,
144 rules: &RoomVersionRules,
145 ) -> Result<Self> {
146 check_rules(&json, &rules.event_format)?;
147 Self::from_object(json)
148 }
149
150 pub fn from_object(json: CanonicalJsonObject) -> Result<Self> {
151 let json = CanonicalJsonValue::Object(json);
152 Self::from_value(json)
153 }
154
155 pub fn from_raw_value(json: &RawJsonValue) -> Result<Self> {
156 let json: CanonicalJsonValue = json.into();
157 Self::from_value(json)
158 }
159
160 pub fn from_value(json: CanonicalJsonValue) -> Result<Self> {
161 serde_json::from_value(json.into()).map_err(Into::into)
162 }
163
164 pub fn from_raw_json(json: &RawJsonValue) -> Result<Self> {
165 Self::deserialize(json).map_err(Into::into)
166 }
167}
168
169impl Event for Pdu
170where
171 Self: Send + Sync + 'static,
172{
173 #[inline]
174 fn auth_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
175 self.auth_events.iter().map(AsRef::as_ref)
176 }
177
178 #[inline]
179 fn auth_events_into(
180 self,
181 ) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + Send {
182 self.auth_events.into_iter()
183 }
184
185 #[inline]
186 fn content(&self) -> &RawJsonValue { self.content.json() }
187
188 #[inline]
189 fn event_id(&self) -> &EventId { &self.event_id }
190
191 #[inline]
192 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
193 MilliSecondsSinceUnixEpoch(self.origin_server_ts)
194 }
195
196 #[inline]
197 fn prev_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
198 self.prev_events.iter().map(AsRef::as_ref)
199 }
200
201 #[inline]
202 fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() }
203
204 #[cfg(test)]
205 #[inline]
206 fn rejected(&self) -> bool { self.rejected }
207
208 #[cfg(not(test))]
209 #[inline]
210 fn rejected(&self) -> bool { false }
211
212 #[inline]
213 fn room_id(&self) -> &RoomId { &self.room_id }
214
215 #[inline]
216 fn sender(&self) -> &UserId { &self.sender }
217
218 #[inline]
219 fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
220
221 #[inline]
222 fn kind(&self) -> &TimelineEventType { &self.kind }
223
224 #[inline]
225 fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_deref() }
226
227 #[inline]
228 fn as_mut_pdu(&mut self) -> &mut Pdu { self }
229
230 #[inline]
231 fn as_pdu(&self) -> &Pdu { self }
232
233 #[inline]
234 fn into_pdu(self) -> Pdu { self }
235
236 #[inline]
237 fn is_owned(&self) -> bool { true }
238}
239
240impl Event for &Pdu
241where
242 Self: Send,
243{
244 #[inline]
245 fn auth_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
246 self.auth_events.iter().map(AsRef::as_ref)
247 }
248
249 #[inline]
250 fn auth_events_into(
251 self,
252 ) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + Send {
253 self.auth_events.iter().map(ToOwned::to_owned)
254 }
255
256 #[inline]
257 fn content(&self) -> &RawJsonValue { self.content.json() }
258
259 #[inline]
260 fn event_id(&self) -> &EventId { &self.event_id }
261
262 #[inline]
263 fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
264 MilliSecondsSinceUnixEpoch(self.origin_server_ts)
265 }
266
267 #[inline]
268 fn prev_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_ {
269 self.prev_events.iter().map(AsRef::as_ref)
270 }
271
272 #[inline]
273 fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() }
274
275 #[cfg(test)]
276 #[inline]
277 fn rejected(&self) -> bool { self.rejected }
278
279 #[cfg(not(test))]
280 #[inline]
281 fn rejected(&self) -> bool { false }
282
283 #[inline]
284 fn room_id(&self) -> &RoomId { &self.room_id }
285
286 #[inline]
287 fn sender(&self) -> &UserId { &self.sender }
288
289 #[inline]
290 fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
291
292 #[inline]
293 fn kind(&self) -> &TimelineEventType { &self.kind }
294
295 #[inline]
296 fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_deref() }
297
298 #[inline]
299 fn as_pdu(&self) -> &Pdu { self }
300
301 #[inline]
302 fn into_pdu(self) -> Pdu { self.clone() }
303
304 #[inline]
305 fn is_owned(&self) -> bool { false }
306}
307
308impl Eq for Pdu {}
310
311impl PartialEq for Pdu {
313 fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id }
314}
315
316impl Ord for Pdu {
318 fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) }
319}
320
321impl PartialOrd for Pdu {
323 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
324}