ruma_client_api/push/set_pusher/
set_pusher_serde.rs1use js_option::JsOption;
2use ruma_common::serde::from_raw_json_value;
3use serde::{Deserialize, Serialize, de, ser::SerializeStruct};
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 ruma_common::canonical_json::assert_to_canonical_json_eq;
72 use serde_json::{from_value as from_json_value, json};
73
74 use super::PusherAction;
75 use crate::push::{
76 EmailPusherData, Pusher, PusherIds, PusherKind, set_pusher::v3::PusherPostData,
77 };
78
79 #[test]
80 fn serialize_post() {
81 let action = PusherAction::Post(PusherPostData {
82 pusher: Pusher {
83 ids: PusherIds::new("abcdef".to_owned(), "my.matrix.app".to_owned()),
84 kind: PusherKind::Email(EmailPusherData::new()),
85 app_display_name: "My Matrix App".to_owned(),
86 device_display_name: "My Phone".to_owned(),
87 profile_tag: None,
88 lang: "en".to_owned(),
89 },
90 append: false,
91 });
92
93 assert_to_canonical_json_eq!(
94 action,
95 json!({
96 "pushkey": "abcdef",
97 "app_id": "my.matrix.app",
98 "kind": "email",
99 "app_display_name": "My Matrix App",
100 "device_display_name": "My Phone",
101 "lang": "en",
102 "data": {}
103 })
104 );
105 }
106
107 #[test]
108 fn serialize_delete() {
109 let action =
110 PusherAction::Delete(PusherIds::new("abcdef".to_owned(), "my.matrix.app".to_owned()));
111
112 assert_to_canonical_json_eq!(
113 action,
114 json!({
115 "pushkey": "abcdef",
116 "app_id": "my.matrix.app",
117 "kind": null,
118 })
119 );
120 }
121
122 #[test]
123 fn deserialize_post() {
124 let json = json!({
125 "pushkey": "abcdef",
126 "app_id": "my.matrix.app",
127 "kind": "email",
128 "app_display_name": "My Matrix App",
129 "device_display_name": "My Phone",
130 "lang": "en",
131 "data": {}
132 });
133
134 assert_matches!(from_json_value(json).unwrap(), PusherAction::Post(post_data));
135 assert!(!post_data.append);
136
137 let pusher = post_data.pusher;
138 assert_eq!(pusher.ids.pushkey, "abcdef");
139 assert_eq!(pusher.ids.app_id, "my.matrix.app");
140 assert_matches!(pusher.kind, PusherKind::Email(_));
141 assert_eq!(pusher.app_display_name, "My Matrix App");
142 assert_eq!(pusher.device_display_name, "My Phone");
143 assert_eq!(pusher.profile_tag, None);
144 assert_eq!(pusher.lang, "en");
145 }
146
147 #[test]
148 fn deserialize_delete() {
149 let json = json!({
150 "pushkey": "abcdef",
151 "app_id": "my.matrix.app",
152 "kind": null,
153 });
154
155 assert_matches!(from_json_value(json).unwrap(), PusherAction::Delete(ids));
156 assert_eq!(ids.pushkey, "abcdef");
157 assert_eq!(ids.app_id, "my.matrix.app");
158 }
159}