Skip to main content

tuwunel_core/matrix/
event.rs

1//! Event access, conversion, filtering, and state-key utilities.
2//!
3//! The module defines the common event trait and adapters for client and
4//! federation representations. It also exposes helpers for inspecting event
5//! data.
6
7mod content;
8mod filter;
9mod format;
10mod id;
11mod redact;
12mod relation;
13pub mod state_key;
14mod type_ext;
15mod unsigned;
16
17use std::fmt::Debug;
18
19use ruma::{
20	CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, UserId,
21	events::TimelineEventType, room_version_rules::RoomVersionRules,
22};
23use serde::Deserialize;
24use serde_json::{Value as JsonValue, value::RawValue as RawJsonValue};
25
26pub use self::{
27	filter::{Matches, trim_event_fields},
28	format::{Owned, Ref},
29	id::*,
30	relation::RelationTypeEqual,
31	state_key::{StateKey, TypeStateKey},
32	type_ext::TypeExt,
33};
34use super::pdu::Pdu;
35use crate::{Result, utils};
36
37/// Abstraction of a PDU so users can have their own PDU types.
38pub trait Event: Clone + Debug + Send + Sync {
39	/// Checks whether this event has both the requested type and state key.
40	///
41	/// Message-like events never match because their state key is absent. The
42	/// comparison does not inspect event content.
43	#[inline]
44	fn is_type_and_state_key(&self, kind: &TimelineEventType, state_key: &str) -> bool {
45		self.kind() == kind && self.state_key() == Some(state_key)
46	}
47
48	/// Serialize into a Ruma JSON format, consuming.
49	#[inline]
50	fn into_format<T>(self) -> T
51	where
52		T: From<Owned<Self>>,
53		Self: Sized,
54	{
55		Owned(self).into()
56	}
57
58	/// Serialize into a Ruma JSON format
59	#[inline]
60	fn to_format<'a, T>(&'a self) -> T
61	where
62		T: From<Ref<'a, Self>>,
63		Self: Sized + 'a,
64	{
65		Ref(self).into()
66	}
67
68	/// Checks an unsigned-data property with a caller-supplied predicate.
69	///
70	/// The method returns false when the property is absent or the predicate
71	/// rejects its value. Missing or malformed unsigned data is treated as
72	/// empty.
73	#[inline]
74	fn contains_unsigned_property<T>(&self, property: &str, is_type: T) -> bool
75	where
76		T: FnOnce(&JsonValue) -> bool,
77		Self: Sized,
78	{
79		unsigned::contains_unsigned_property::<T, _>(self, property, is_type)
80	}
81
82	/// Deserializes one property from the event's unsigned data.
83	///
84	/// A missing property or malformed unsigned data is reported as not found.
85	/// A value of the wrong type fails deserialization.
86	#[inline]
87	fn get_unsigned_property<T>(&self, property: &str) -> Result<T>
88	where
89		T: for<'de> Deserialize<'de>,
90		Self: Sized,
91	{
92		unsigned::get_unsigned_property::<T, _>(self, property)
93	}
94
95	/// Deserializes the event's unsigned data as a JSON value.
96	///
97	/// Missing or malformed unsigned data produces JSON null. Use
98	/// `get_unsigned` when the distinction must be preserved.
99	#[inline]
100	fn get_unsigned_as_value(&self) -> JsonValue
101	where
102		Self: Sized,
103	{
104		unsigned::get_unsigned_as_value(self)
105	}
106
107	/// Deserializes the complete unsigned-data object into a requested type.
108	///
109	/// Missing unsigned data is reported as not found. Invalid JSON or a type
110	/// mismatch fails deserialization.
111	#[inline]
112	fn get_unsigned<T>(&self) -> Result<T>
113	where
114		T: for<'de> Deserialize<'de>,
115		Self: Sized,
116	{
117		unsigned::get_unsigned::<T, _>(self)
118	}
119
120	/// Deserializes event content as an untyped JSON value.
121	///
122	/// The returned value owns its data and can be inspected without borrowing
123	/// the event. Typed consumers should prefer `get_content`.
124	///
125	/// # Panics
126	///
127	/// Panics when the stored content is not valid JSON.
128	#[inline]
129	fn get_content_as_value(&self) -> JsonValue
130	where
131		Self: Sized,
132	{
133		content::as_value(self)
134	}
135
136	/// Deserializes event content into a requested type.
137	///
138	/// The target type determines which event-content shape is accepted.
139	/// Invalid JSON or a mismatched target type produces a bad-JSON result.
140	#[inline]
141	fn get_content<T>(&self) -> Result<T>
142	where
143		for<'de> T: Deserialize<'de>,
144		Self: Sized,
145	{
146		content::get::<T, _>(self)
147	}
148
149	/// Resolves the event ID targeted by a redaction event.
150	///
151	/// The selected room rules determine whether the ID is read from event
152	/// content or the top-level `redacts` field. Non-redaction events and
153	/// malformed content return `None`.
154	#[inline]
155	fn redacts_id(&self, room_rules: &RoomVersionRules) -> Option<OwnedEventId>
156	where
157		Self: Sized,
158	{
159		redact::redacts_id(self, room_rules)
160	}
161
162	/// Reports whether the event carries redaction metadata.
163	///
164	/// Redaction is recognized by the presence of `unsigned.redacted_because`.
165	/// Missing or malformed unsigned data is treated as not redacted.
166	#[inline]
167	fn is_redacted(&self) -> bool
168	where
169		Self: Sized,
170	{
171		redact::is_redacted(self)
172	}
173
174	/// Consumes the event and serializes its PDU as a canonical JSON object.
175	///
176	/// Implementations first convert the event to the common `Pdu`
177	/// representation. The resulting object preserves the stored event fields.
178	///
179	/// # Panics
180	///
181	/// Panics if the PDU cannot be serialized as a canonical JSON object.
182	#[inline]
183	fn into_canonical_object(self) -> CanonicalJsonObject
184	where
185		Self: Sized,
186	{
187		utils::to_canonical_object(self.into_pdu()).expect("failed to create Value::Object")
188	}
189
190	/// Serializes the event's PDU as an owned canonical JSON object.
191	///
192	/// The event remains available after conversion. The resulting object
193	/// preserves the stored event fields.
194	///
195	/// # Panics
196	///
197	/// Panics if the PDU cannot be serialized as a canonical JSON object.
198	#[inline]
199	fn to_canonical_object(&self) -> CanonicalJsonObject {
200		utils::to_canonical_object(self.as_pdu()).expect("failed to create Value::Object")
201	}
202
203	/// Consumes the event and serializes its PDU as a JSON value.
204	///
205	/// Implementations first convert the event to the common `Pdu`
206	/// representation. The returned value is an owned JSON object.
207	///
208	/// # Panics
209	///
210	/// Panics if the PDU cannot be serialized as JSON.
211	#[inline]
212	fn into_value(self) -> JsonValue
213	where
214		Self: Sized,
215	{
216		serde_json::to_value(self.into_pdu()).expect("failed to create JSON Value")
217	}
218
219	/// Serializes the event's PDU as an owned JSON value.
220	///
221	/// The event remains available after conversion. The returned value is an
222	/// owned JSON object.
223	///
224	/// # Panics
225	///
226	/// Panics if the PDU cannot be serialized as JSON.
227	#[inline]
228	fn to_value(&self) -> JsonValue {
229		serde_json::to_value(self.as_pdu()).expect("failed to create JSON Value")
230	}
231
232	/// Returns mutable access to the common PDU representation.
233	///
234	/// Implementations backed by a mutable `Pdu` override this method. The
235	/// default implementation marks mutable conversion as unsupported.
236	///
237	/// # Panics
238	///
239	/// Panics when the implementation does not provide mutable PDU access.
240	#[inline]
241	fn as_mut_pdu(&mut self) -> &mut Pdu { unimplemented!("not a mutable Pdu") }
242
243	/// Borrows the event as the common PDU representation.
244	///
245	/// Implementations may return their underlying PDU directly or a borrowed
246	/// PDU representation with the same event data.
247	fn as_pdu(&self) -> &Pdu;
248
249	/// Converts the event into an owned common PDU representation.
250	///
251	/// Owned implementations can move their PDU. Borrowed implementations clone
252	/// the PDU so the returned value owns every field.
253	fn into_pdu(self) -> Pdu;
254
255	/// Reports whether consuming conversion can move an owned PDU.
256	///
257	/// A false result indicates that `into_pdu` must clone borrowed event data.
258	/// The value can help callers choose a conversion path.
259	fn is_owned(&self) -> bool;
260
261	//
262	// Canonical properties
263	//
264
265	/// All the authenticating events for this event.
266	fn auth_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_;
267
268	/// All the authenticating events for this event.
269	fn auth_events_into(
270		self,
271	) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + Send;
272
273	/// The event's content.
274	fn content(&self) -> &RawJsonValue;
275
276	/// The `EventId` of this event.
277	fn event_id(&self) -> &EventId;
278
279	/// The time of creation on the originating server.
280	fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch;
281
282	/// The events before this event.
283	fn prev_events(&self) -> impl DoubleEndedIterator<Item = &EventId> + Clone + Send + '_;
284
285	/// If this event is a redaction event this is the event it redacts.
286	fn redacts(&self) -> Option<&EventId>;
287
288	/// see: <https://spec.matrix.org/v1.14/rooms/v11/#rejected-events>
289	fn rejected(&self) -> bool;
290
291	/// The `RoomId` of this event.
292	fn room_id(&self) -> &RoomId;
293
294	/// The `UserId` of this event.
295	fn sender(&self) -> &UserId;
296
297	/// The state key for this event.
298	fn state_key(&self) -> Option<&str>;
299
300	/// The event type.
301	fn kind(&self) -> &TimelineEventType;
302
303	/// Metadata container; peer-trusted only.
304	fn unsigned(&self) -> Option<&RawJsonValue>;
305
306	//#[deprecated]
307	/// Returns the event's timeline type.
308	///
309	/// This compatibility accessor delegates directly to `kind`. New callers
310	/// can use either name without changing the returned value.
311	#[inline]
312	fn event_type(&self) -> &TimelineEventType { self.kind() }
313}