Skip to main content

tuwunel_core/matrix/pdu/
builder.rs

1use std::{collections::BTreeMap, fmt};
2
3use ruma::{
4	MilliSecondsSinceUnixEpoch, OwnedEventId,
5	events::{MessageLikeEventContent, StateEventContent, TimelineEventType},
6};
7use serde::Deserialize;
8use serde_json::value::{RawValue as RawJsonValue, to_raw_value};
9
10use super::StateKey;
11
12/// Build the start of a PDU in order to add it to the Database.
13#[derive(Deserialize)]
14pub struct Builder {
15	#[serde(rename = "type")]
16	pub event_type: TimelineEventType,
17
18	pub content: Box<RawJsonValue>,
19
20	pub unsigned: Option<Unsigned>,
21
22	pub state_key: Option<StateKey>,
23
24	pub redacts: Option<OwnedEventId>,
25
26	/// For timestamped messaging, should only be used for appservices.
27	/// Will be set to current time if None
28	pub timestamp: Option<MilliSecondsSinceUnixEpoch>,
29}
30
31type Unsigned = BTreeMap<String, serde_json::Value>;
32
33impl Default for Builder {
34	fn default() -> Self {
35		Self {
36			event_type: "m.room.message".into(),
37			content: Box::<RawJsonValue>::default(),
38			unsigned: None,
39			state_key: None,
40			redacts: None,
41			timestamp: None,
42		}
43	}
44}
45
46impl Builder {
47	pub fn state<S, T>(state_key: S, content: &T) -> Self
48	where
49		T: StateEventContent,
50		S: Into<StateKey>,
51	{
52		Self {
53			event_type: content.event_type().into(),
54			content: to_raw_value(content)
55				.expect("Builder failed to serialize state event content to RawValue"),
56			state_key: Some(state_key.into()),
57			..Self::default()
58		}
59	}
60
61	pub fn timeline<T>(content: &T) -> Self
62	where
63		T: MessageLikeEventContent,
64	{
65		Self {
66			event_type: content.event_type().into(),
67			content: to_raw_value(content)
68				.expect("Builder failed to serialize timeline event content to RawValue"),
69			..Self::default()
70		}
71	}
72}
73
74impl fmt::Debug for Builder {
75	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76		let mut d = f.debug_struct("Builder");
77
78		d.field("type", &self.event_type);
79
80		if let Some(state_key) = self.state_key.as_ref() {
81			d.field("state_key", state_key);
82		}
83
84		if let Some(redacts) = self.redacts.as_ref() {
85			d.field("redacts", redacts);
86		}
87
88		if let Some(timestamp) = self.timestamp.as_ref() {
89			d.field("ts", timestamp);
90		}
91
92		if let Some(unsigned) = self.unsigned.as_ref() {
93			d.field("unsigned", unsigned);
94		}
95
96		d.field("content", &self.content);
97
98		d.finish()
99	}
100}