tauri_plugin_matrix_svelte/models/matrix_requests.rs
1use matrix_sdk::ruma::{
2 events::room::message::RoomMessageEventContent, OwnedEventId, OwnedRoomId, OwnedUserId,
3};
4use serde::{Deserialize, Deserializer};
5use serde_json::Value;
6
7use crate::matrix::{requests::MatrixRequest, timeline::PaginationDirection};
8
9impl<'de> Deserialize<'de> for MatrixRequest {
10 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
11 where
12 D: Deserializer<'de>,
13 {
14 // First deserialize into a generic Value to inspect the structure
15 let value = Value::deserialize(deserializer)?;
16
17 // Extract the "event" field to determine the variant
18 let event = value
19 .get("event")
20 .and_then(|v| v.as_str())
21 .ok_or_else(|| serde::de::Error::missing_field("event"))?;
22
23 // Extract the "payload" field containing the variant data
24 let payload = value
25 .get("payload")
26 .ok_or_else(|| serde::de::Error::missing_field("payload"))?;
27
28 // Match on the event type and deserialize the appropriate variant
29 match event {
30 "paginateRoomTimeline" => {
31 let data: PaginateRoomTimelinePayload =
32 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
33 Ok(MatrixRequest::PaginateRoomTimeline {
34 room_id: data.room_id,
35 num_events: data.num_events,
36 direction: data.direction,
37 })
38 }
39 // "editMessage" => {
40 // let data: EditMessagePayload =
41 // serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
42 // Ok(MatrixRequest::EditMessage {
43 // room_id: data.room_id,
44 // timeline_event_item_id: data.timeline_event_item_id,
45 // edited_content: data.edited_content,
46 // })
47 // }
48 "fetchDetailsForEvent" => {
49 let data: FetchDetailsForEventPayload =
50 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
51 Ok(MatrixRequest::FetchDetailsForEvent {
52 room_id: data.room_id,
53 event_id: data.event_id,
54 })
55 }
56 // "syncRoomMemberList" => {
57 // let data: SyncRoomMemberListPayload =
58 // serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
59 // Ok(MatrixRequest::SyncRoomMemberList {
60 // room_id: data.room_id,
61 // })
62 // }
63 "joinRoom" => {
64 let data: JoinRoomPayload =
65 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
66 Ok(MatrixRequest::JoinRoom {
67 room_id: data.room_id,
68 })
69 }
70 "leaveRoom" => {
71 let data: LeaveRoomPayload =
72 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
73 Ok(MatrixRequest::LeaveRoom {
74 room_id: data.room_id,
75 })
76 }
77 // "getRoomMembers" => {
78 // let data: GetRoomMembersPayload =
79 // serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
80 // Ok(MatrixRequest::GetRoomMembers {
81 // room_id: data.room_id,
82 // memberships: data.memberships,
83 // local_only: data.local_only,
84 // })
85 // }
86 "getUserProfile" => {
87 let data: GetUserProfilePayload =
88 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
89 Ok(MatrixRequest::GetUserProfile {
90 user_id: data.user_id,
91 room_id: data.room_id,
92 local_only: data.local_only,
93 })
94 }
95 "getNumberUnreadMessages" => {
96 let data: GetNumberUnreadMessagesPayload =
97 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
98 Ok(MatrixRequest::GetNumberUnreadMessages {
99 room_id: data.room_id,
100 })
101 }
102 // "ignoreUser" => {
103 // let data: IgnoreUserPayload =
104 // serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
105 // Ok(MatrixRequest::IgnoreUser {
106 // ignore: data.ignore,
107 // room_member: data.room_member,
108 // room_id: data.room_id,
109 // })
110 // }
111 "resolveRoomAlias" => {
112 let alias =
113 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
114 Ok(MatrixRequest::ResolveRoomAlias(alias))
115 }
116 "sendMessage" => {
117 let data: SendMessagePayload =
118 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
119 Ok(MatrixRequest::SendMessage {
120 room_id: data.room_id,
121 message: data.message,
122 })
123 }
124 "sendTypingNotice" => {
125 let data: SendTypingNoticePayload =
126 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
127 Ok(MatrixRequest::SendTypingNotice {
128 room_id: data.room_id,
129 typing: data.typing,
130 })
131 }
132 "subscribeToTypingNotices" => {
133 let data: SubscribeToTypingNoticesPayload =
134 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
135 Ok(MatrixRequest::SubscribeToTypingNotices {
136 room_id: data.room_id,
137 subscribe: data.subscribe,
138 })
139 }
140 "subscribeToOwnUserReadReceiptsChanged" => {
141 let data: SubscribeToOwnUserReadReceiptsChangedPayload =
142 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
143 Ok(MatrixRequest::SubscribeToOwnUserReadReceiptsChanged {
144 room_id: data.room_id,
145 subscribe: data.subscribe,
146 })
147 }
148 "readReceipt" => {
149 let data: ReadReceiptPayload =
150 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
151 Ok(MatrixRequest::ReadReceipt {
152 room_id: data.room_id,
153 event_id: data.event_id,
154 })
155 }
156 "fullyReadReceipt" => {
157 let data: FullyReadReceiptPayload =
158 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
159 Ok(MatrixRequest::FullyReadReceipt {
160 room_id: data.room_id,
161 event_id: data.event_id,
162 })
163 }
164 "getRoomPowerLevels" => {
165 let data: GetRoomPowerLevelsPayload =
166 serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
167 Ok(MatrixRequest::GetRoomPowerLevels {
168 room_id: data.room_id,
169 })
170 }
171 // "toggleReaction" => {
172 // let data: ToggleReactionPayload =
173 // serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
174 // Ok(MatrixRequest::ToggleReaction {
175 // room_id: data.room_id,
176 // timeline_event_id: data.timeline_event_id,
177 // reaction: data.reaction,
178 // })
179 // }
180 // "redactMessage" => {
181 // let data: RedactMessagePayload =
182 // serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
183 // Ok(MatrixRequest::RedactMessage {
184 // room_id: data.room_id,
185 // timeline_event_id: data.timeline_event_id,
186 // reason: data.reason,
187 // })
188 // }
189 // "getMatrixRoomLinkPillInfo" => {
190 // let data: GetMatrixRoomLinkPillInfoPayload =
191 // serde_json::from_value(payload.clone()).map_err(serde::de::Error::custom)?;
192 // Ok(MatrixRequest::GetMatrixRoomLinkPillInfo {
193 // matrix_id: data.matrix_id,
194 // via: data.via,
195 // })
196 // }
197 _ => Err(serde::de::Error::unknown_variant(
198 event,
199 &[
200 "paginateRoomTimeline",
201 // "editMessage",
202 "fetchDetailsForEvent",
203 // "syncRoomMemberList",
204 "joinRoom",
205 "leaveRoom",
206 // "getRoomMembers",
207 "getUserProfile",
208 "getNumberUnreadMessages",
209 // "ignoreUser",
210 "resolveRoomAlias",
211 "sendMessage",
212 "sendTypingNotice",
213 "subscribeToTypingNotices",
214 "subscribeToOwnUserReadReceiptsChanged",
215 "readReceipt",
216 "fullyReadReceipt",
217 "getRoomPowerLevels",
218 // "toggleReaction",
219 // "redactMessage",
220 // "getMatrixRoomLinkPillInfo",
221 ],
222 )),
223 }
224 }
225}
226
227// Helper structs for deserializing payloads
228#[derive(Deserialize)]
229#[serde(rename_all = "camelCase")]
230struct PaginateRoomTimelinePayload {
231 room_id: OwnedRoomId,
232 num_events: u16,
233 direction: PaginationDirection,
234}
235
236// #[derive(Deserialize)]
237// #[serde(rename_all = "camelCase")]
238// struct EditMessagePayload {
239// room_id: OwnedRoomId,
240// timeline_event_item_id: TimelineEventItemId,
241// edited_content: EditedContent,
242// }
243
244#[derive(Deserialize)]
245#[serde(rename_all = "camelCase")]
246struct FetchDetailsForEventPayload {
247 room_id: OwnedRoomId,
248 event_id: OwnedEventId,
249}
250
251// #[derive(Deserialize)]
252// #[serde(rename_all = "camelCase")]
253// struct SyncRoomMemberListPayload {
254// room_id: OwnedRoomId,
255// }
256
257#[derive(Deserialize)]
258#[serde(rename_all = "camelCase")]
259struct JoinRoomPayload {
260 room_id: OwnedRoomId,
261}
262
263#[derive(Deserialize)]
264#[serde(rename_all = "camelCase")]
265struct LeaveRoomPayload {
266 room_id: OwnedRoomId,
267}
268
269// #[derive(Deserialize)]
270// #[serde(rename_all = "camelCase")]
271// struct GetRoomMembersPayload {
272// room_id: OwnedRoomId,
273// memberships: RoomMemberships,
274// local_only: bool,
275// }
276
277#[derive(Deserialize)]
278#[serde(rename_all = "camelCase")]
279struct GetUserProfilePayload {
280 user_id: OwnedUserId,
281 room_id: Option<OwnedRoomId>,
282 local_only: bool,
283}
284
285#[derive(Deserialize)]
286#[serde(rename_all = "camelCase")]
287struct GetNumberUnreadMessagesPayload {
288 room_id: OwnedRoomId,
289}
290
291// #[derive(Deserialize)]
292// #[serde(rename_all = "camelCase")]
293// struct IgnoreUserPayload {
294// ignore: bool,
295// room_member: RoomMember,
296// room_id: OwnedRoomId,
297// }
298
299#[derive(Deserialize)]
300#[serde(rename_all = "camelCase")]
301struct SendMessagePayload {
302 room_id: OwnedRoomId,
303 message: RoomMessageEventContent,
304}
305
306#[derive(Deserialize)]
307#[serde(rename_all = "camelCase")]
308struct SendTypingNoticePayload {
309 room_id: OwnedRoomId,
310 typing: bool,
311}
312
313#[derive(Deserialize)]
314#[serde(rename_all = "camelCase")]
315struct SubscribeToTypingNoticesPayload {
316 room_id: OwnedRoomId,
317 subscribe: bool,
318}
319
320#[derive(Deserialize)]
321#[serde(rename_all = "camelCase")]
322struct SubscribeToOwnUserReadReceiptsChangedPayload {
323 room_id: OwnedRoomId,
324 subscribe: bool,
325}
326
327#[derive(Deserialize)]
328#[serde(rename_all = "camelCase")]
329struct ReadReceiptPayload {
330 room_id: OwnedRoomId,
331 event_id: OwnedEventId,
332}
333
334#[derive(Deserialize)]
335#[serde(rename_all = "camelCase")]
336struct FullyReadReceiptPayload {
337 room_id: OwnedRoomId,
338 event_id: OwnedEventId,
339}
340
341#[derive(Deserialize)]
342#[serde(rename_all = "camelCase")]
343struct GetRoomPowerLevelsPayload {
344 room_id: OwnedRoomId,
345}
346
347// #[derive(Deserialize)]
348// #[serde(rename_all = "camelCase")]
349// struct ToggleReactionPayload {
350// room_id: OwnedRoomId,
351// timeline_event_id: TimelineEventItemId,
352// reaction: String,
353// }
354
355// #[derive(Deserialize)]
356// #[serde(rename_all = "camelCase")]
357// struct RedactMessagePayload {
358// room_id: OwnedRoomId,
359// timeline_event_id: TimelineEventItemId,
360// reason: Option<String>,
361// }
362
363// #[derive(Deserialize)]
364// #[serde(rename_all = "camelCase")]
365// struct GetMatrixRoomLinkPillInfoPayload {
366// matrix_id: MatrixId,
367// via: Vec<OwnedServerName>,
368// }