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)]
18pub struct Builder {
19 #[serde(rename = "type")]
23 pub event_type: TimelineEventType,
24
25 pub content: Content,
30
31 pub unsigned: Option<BTreeMap<String, serde_json::Value>>,
35
36 pub state_key: Option<StateKey>,
40
41 pub redacts: Option<OwnedEventId>,
46
47 pub timestamp: Option<MilliSecondsSinceUnixEpoch>,
52}
53
54impl Default for Builder {
55 fn default() -> Self {
56 Self {
57 event_type: "m.room.message".into(),
58 content: Box::<RawJsonValue>::default().into(),
59 unsigned: None,
60 state_key: None,
61 redacts: None,
62 timestamp: None,
63 }
64 }
65}
66
67impl Builder {
68 pub fn state<S, T>(state_key: S, content: &T) -> Self
78 where
79 T: StateEventContent,
80 S: Into<StateKey>,
81 {
82 Self {
83 event_type: content.event_type().into(),
84 content: to_raw_value(content)
85 .map(Into::into)
86 .expect("Builder failed to serialize state event content to RawValue"),
87 state_key: Some(state_key.into()),
88 ..Self::default()
89 }
90 }
91
92 pub fn timeline<T>(content: &T) -> Self
101 where
102 T: MessageLikeEventContent,
103 {
104 Self {
105 event_type: content.event_type().into(),
106 content: to_raw_value(content)
107 .map(Into::into)
108 .expect("Builder failed to serialize timeline event content to RawValue"),
109 ..Self::default()
110 }
111 }
112}
113
114impl fmt::Debug for Builder {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 let mut d = f.debug_struct("Builder");
117
118 d.field("type", &self.event_type);
119
120 if let Some(state_key) = self.state_key.as_ref() {
121 d.field("state_key", state_key);
122 }
123
124 if let Some(redacts) = self.redacts.as_ref() {
125 d.field("redacts", redacts);
126 }
127
128 if let Some(timestamp) = self.timestamp.as_ref() {
129 d.field("ts", timestamp);
130 }
131
132 if let Some(unsigned) = self.unsigned.as_ref() {
133 d.field("unsigned", unsigned);
134 }
135
136 d.field("content", &self.content);
137
138 d.finish()
139 }
140}