ruma_client_api/push/set_pusher/
set_pusher_serde.rs
1use js_option::JsOption;
2use ruma_common::serde::from_raw_json_value;
3use serde::{de, ser::SerializeStruct, Deserialize, Serialize};
4use serde_json::value::RawValue as RawJsonValue;
5
6use super::v3::{PusherAction, PusherPostData};
7
8#[derive(Debug, Deserialize)]
9struct PusherPostDataDeHelper {
10 #[serde(default)]
11 append: bool,
12}
13
14impl<'de> Deserialize<'de> for PusherPostData {
15 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
16 where
17 D: de::Deserializer<'de>,
18 {
19 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
20
21 let PusherPostDataDeHelper { append } = from_raw_json_value(&json)?;
22 let pusher = from_raw_json_value(&json)?;
23
24 Ok(Self { pusher, append })
25 }
26}
27
28impl Serialize for PusherAction {
29 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
30 where
31 S: serde::Serializer,
32 {
33 match self {
34 PusherAction::Post(pusher) => pusher.serialize(serializer),
35 PusherAction::Delete(ids) => {
36 let mut st = serializer.serialize_struct("PusherAction", 3)?;
37 st.serialize_field("pushkey", &ids.pushkey)?;
38 st.serialize_field("app_id", &ids.app_id)?;
39 st.serialize_field("kind", &None::<&str>)?;
40 st.end()
41 }
42 }
43 }
44}
45
46#[derive(Debug, Deserialize)]
47struct PusherActionDeHelper {
48 kind: JsOption<String>,
49}
50
51impl<'de> Deserialize<'de> for PusherAction {
52 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53 where
54 D: de::Deserializer<'de>,
55 {
56 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
57 let PusherActionDeHelper { kind } = from_raw_json_value(&json)?;
58
59 match kind {
60 JsOption::Some(_) => Ok(Self::Post(from_raw_json_value(&json)?)),
61 JsOption::Null => Ok(Self::Delete(from_raw_json_value(&json)?)),
62 JsOption::Undefined => Err(de::Error::missing_field("kind")),
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use assert_matches2::assert_matches;
71 use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
72
73 use super::PusherAction;
74 use crate::push::{
75 set_pusher::v3::PusherPostData, EmailPusherData, Pusher, PusherIds, PusherKind,
76 };
77
78 #[test]
79 fn serialize_post() {
80 let action = PusherAction::Post(PusherPostData {
81 pusher: Pusher {
82 ids: PusherIds::new("abcdef".to_owned(), "my.matrix.app".to_owned()),
83 kind: PusherKind::Email(EmailPusherData::new()),
84 app_display_name: "My Matrix App".to_owned(),
85 device_display_name: "My Phone".to_owned(),
86 profile_tag: None,
87 lang: "en".to_owned(),
88 },
89 append: false,
90 });
91
92 assert_eq!(
93 to_json_value(action).unwrap(),
94 json!({
95 "pushkey": "abcdef",
96 "app_id": "my.matrix.app",
97 "kind": "email",
98 "app_display_name": "My Matrix App",
99 "device_display_name": "My Phone",
100 "lang": "en",
101 "data": {}
102 })
103 );
104 }
105
106 #[test]
107 fn serialize_delete() {
108 let action =
109 PusherAction::Delete(PusherIds::new("abcdef".to_owned(), "my.matrix.app".to_owned()));
110
111 assert_eq!(
112 to_json_value(action).unwrap(),
113 json!({
114 "pushkey": "abcdef",
115 "app_id": "my.matrix.app",
116 "kind": null,
117 })
118 );
119 }
120
121 #[test]
122 fn deserialize_post() {
123 let json = json!({
124 "pushkey": "abcdef",
125 "app_id": "my.matrix.app",
126 "kind": "email",
127 "app_display_name": "My Matrix App",
128 "device_display_name": "My Phone",
129 "lang": "en",
130 "data": {}
131 });
132
133 assert_matches!(from_json_value(json).unwrap(), PusherAction::Post(post_data));
134 assert!(!post_data.append);
135
136 let pusher = post_data.pusher;
137 assert_eq!(pusher.ids.pushkey, "abcdef");
138 assert_eq!(pusher.ids.app_id, "my.matrix.app");
139 assert_matches!(pusher.kind, PusherKind::Email(_));
140 assert_eq!(pusher.app_display_name, "My Matrix App");
141 assert_eq!(pusher.device_display_name, "My Phone");
142 assert_eq!(pusher.profile_tag, None);
143 assert_eq!(pusher.lang, "en");
144 }
145
146 #[test]
147 fn deserialize_delete() {
148 let json = json!({
149 "pushkey": "abcdef",
150 "app_id": "my.matrix.app",
151 "kind": null,
152 });
153
154 assert_matches!(from_json_value(json).unwrap(), PusherAction::Delete(ids));
155 assert_eq!(ids.pushkey, "abcdef");
156 assert_eq!(ids.app_id, "my.matrix.app");
157 }
158}