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::StateKey;
11
12#[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 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}