tuwunel_core/matrix/pdu/
builder.rs1use 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#[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 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}