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// }