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::{Content, 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: Content,
19
20	pub unsigned: Option<BTreeMap<String, serde_json::Value>>,
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
31impl Default for Builder {
32	fn default() -> Self {
33		Self {
34			event_type: "m.room.message".into(),
35			content: Box::<RawJsonValue>::default().into(),
36			unsigned: None,
37			state_key: None,
38			redacts: None,
39			timestamp: None,
40		}
41	}
42}
43
44impl Builder {
45	pub fn state<S, T>(state_key: S, content: &T) -> Self
46	where
47		T: StateEventContent,
48		S: Into<StateKey>,
49	{
50		Self {
51			event_type: content.event_type().into(),
52			content: to_raw_value(content)
53				.map(Into::into)
54				.expect("Builder failed to serialize state event content to RawValue"),
55			state_key: Some(state_key.into()),
56			..Self::default()
57		}
58	}
59
60	pub fn timeline<T>(content: &T) -> Self
61	where
62		T: MessageLikeEventContent,
63	{
64		Self {
65			event_type: content.event_type().into(),
66			content: to_raw_value(content)
67				.map(Into::into)
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}