svc_agent/
serde.rs

1use serde::{de, ser};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5use crate::{
6    mqtt::agent::{Connection, ConnectionMode},
7    mqtt::TrackingId,
8    AgentId, SharedGroup,
9};
10
11////////////////////////////////////////////////////////////////////////////////
12
13#[derive(Deserialize, Serialize)]
14#[serde(remote = "http::StatusCode")]
15pub(crate) struct HttpStatusCodeRef(#[serde(getter = "http_status_code_to_string")] String);
16
17fn http_status_code_to_string(status_code: &http::StatusCode) -> String {
18    status_code.as_u16().to_string()
19}
20
21impl From<HttpStatusCodeRef> for http::StatusCode {
22    fn from(value: HttpStatusCodeRef) -> http::StatusCode {
23        use std::str::FromStr;
24
25        http::StatusCode::from_str(&value.0).unwrap()
26    }
27}
28
29////////////////////////////////////////////////////////////////////////////////
30
31impl ser::Serialize for AgentId {
32    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
33    where
34        S: ser::Serializer,
35    {
36        serializer.serialize_str(&self.to_string())
37    }
38}
39
40impl<'de> de::Deserialize<'de> for AgentId {
41    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
42    where
43        D: de::Deserializer<'de>,
44    {
45        struct AgentIdVisitor;
46
47        impl<'de> de::Visitor<'de> for AgentIdVisitor {
48            type Value = AgentId;
49
50            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
51                formatter.write_str("struct AgentId")
52            }
53
54            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
55            where
56                E: de::Error,
57            {
58                use std::str::FromStr;
59
60                AgentId::from_str(v)
61                    .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self))
62            }
63        }
64
65        deserializer.deserialize_str(AgentIdVisitor)
66    }
67}
68
69////////////////////////////////////////////////////////////////////////////////
70
71impl ser::Serialize for SharedGroup {
72    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73    where
74        S: ser::Serializer,
75    {
76        serializer.serialize_str(&self.to_string())
77    }
78}
79
80impl<'de> de::Deserialize<'de> for SharedGroup {
81    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82    where
83        D: de::Deserializer<'de>,
84    {
85        struct SharedGroupVisitor;
86
87        impl<'de> de::Visitor<'de> for SharedGroupVisitor {
88            type Value = SharedGroup;
89
90            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
91                formatter.write_str("struct SharedGroup")
92            }
93
94            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
95            where
96                E: de::Error,
97            {
98                use std::str::FromStr;
99
100                SharedGroup::from_str(v)
101                    .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self))
102            }
103        }
104
105        deserializer.deserialize_str(SharedGroupVisitor)
106    }
107}
108
109////////////////////////////////////////////////////////////////////////////////
110
111impl ser::Serialize for ConnectionMode {
112    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113    where
114        S: ser::Serializer,
115    {
116        serializer.serialize_str(&self.to_string())
117    }
118}
119
120impl<'de> de::Deserialize<'de> for ConnectionMode {
121    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
122    where
123        D: de::Deserializer<'de>,
124    {
125        struct ConnectionModeVisitor;
126
127        impl<'de> de::Visitor<'de> for ConnectionModeVisitor {
128            type Value = ConnectionMode;
129
130            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
131                formatter.write_str("enum ConnectionMode")
132            }
133
134            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
135            where
136                E: de::Error,
137            {
138                use std::str::FromStr;
139
140                ConnectionMode::from_str(v)
141                    .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self))
142            }
143        }
144
145        deserializer.deserialize_str(ConnectionModeVisitor)
146    }
147}
148
149////////////////////////////////////////////////////////////////////////////////
150
151impl ser::Serialize for Connection {
152    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
153    where
154        S: ser::Serializer,
155    {
156        serializer.serialize_str(&self.to_string())
157    }
158}
159
160impl<'de> de::Deserialize<'de> for Connection {
161    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
162    where
163        D: de::Deserializer<'de>,
164    {
165        struct ConnectionVisitor;
166
167        impl<'de> de::Visitor<'de> for ConnectionVisitor {
168            type Value = Connection;
169
170            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
171                formatter.write_str("struct Connection")
172            }
173
174            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
175            where
176                E: de::Error,
177            {
178                use std::str::FromStr;
179
180                Connection::from_str(v)
181                    .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self))
182            }
183        }
184
185        deserializer.deserialize_str(ConnectionVisitor)
186    }
187}
188
189///////////////////////////////////////////////////////////////////////////////
190
191pub(crate) mod ts_milliseconds_string {
192    use std::fmt;
193
194    use chrono::{offset::TimeZone, DateTime, LocalResult, Utc};
195    use serde::{de, ser};
196
197    pub(crate) fn serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error>
198    where
199        S: ser::Serializer,
200    {
201        serializer.serialize_str(&dt.timestamp_millis().to_string())
202    }
203
204    pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error>
205    where
206        D: de::Deserializer<'de>,
207    {
208        d.deserialize_any(TimestampMillisecondsVisitor)
209    }
210
211    pub struct TimestampMillisecondsVisitor;
212
213    impl<'de> de::Visitor<'de> for TimestampMillisecondsVisitor {
214        type Value = DateTime<Utc>;
215
216        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
217            formatter.write_str("unix time (milliseconds as string)")
218        }
219
220        fn visit_str<E>(self, value_str: &str) -> Result<Self::Value, E>
221        where
222            E: de::Error,
223        {
224            match value_str.parse::<u64>() {
225                Ok(value) => {
226                    let local_result = Utc
227                        .timestamp_opt((value / 1000) as i64, ((value % 1000) * 1_000_000) as u32);
228
229                    match local_result {
230                        LocalResult::Single(ms) => Ok(ms),
231                        _ => Err(E::custom(format!(
232                            "failed to parse milliseconds: {}",
233                            value
234                        ))),
235                    }
236                }
237                Err(err) => Err(E::custom(format!(
238                    "failed to parse integer from string: {}",
239                    err
240                ))),
241            }
242        }
243    }
244}
245
246pub(crate) mod ts_milliseconds_string_option {
247    use std::fmt;
248
249    use chrono::{DateTime, Utc};
250    use serde::{de, ser};
251
252    use super::ts_milliseconds_string;
253
254    pub(crate) fn serialize<S>(
255        option: &Option<DateTime<Utc>>,
256        serializer: S,
257    ) -> Result<S::Ok, S::Error>
258    where
259        S: ser::Serializer,
260    {
261        match option {
262            Some(value) => ts_milliseconds_string::serialize(value, serializer),
263            None => serializer.serialize_none(),
264        }
265    }
266
267    pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error>
268    where
269        D: de::Deserializer<'de>,
270    {
271        d.deserialize_option(TimestampMillisecondsOptionVisitor)
272    }
273
274    pub struct TimestampMillisecondsOptionVisitor;
275
276    impl<'de> de::Visitor<'de> for TimestampMillisecondsOptionVisitor {
277        type Value = Option<DateTime<Utc>>;
278
279        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
280            formatter.write_str("optional unix time (milliseconds as string)")
281        }
282
283        fn visit_none<E>(self) -> Result<Self::Value, E>
284        where
285            E: de::Error,
286        {
287            Ok(None)
288        }
289
290        fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
291        where
292            D: de::Deserializer<'de>,
293        {
294            let value = ts_milliseconds_string::deserialize(d)?;
295            Ok(Some(value))
296        }
297    }
298}
299
300///////////////////////////////////////////////////////////////////////////////
301
302pub(crate) mod duration_milliseconds_string {
303    use std::fmt;
304
305    use chrono::Duration;
306    use serde::{de, ser};
307
308    pub(crate) fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
309    where
310        S: ser::Serializer,
311    {
312        serializer.serialize_str(&duration.num_milliseconds().to_string())
313    }
314
315    pub fn deserialize<'de, D>(d: D) -> Result<Duration, D::Error>
316    where
317        D: de::Deserializer<'de>,
318    {
319        d.deserialize_any(DurationMillisecondsVisitor)
320    }
321
322    pub struct DurationMillisecondsVisitor;
323
324    impl<'de> de::Visitor<'de> for DurationMillisecondsVisitor {
325        type Value = Duration;
326
327        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
328            formatter.write_str("duration (milliseconds as string)")
329        }
330
331        fn visit_str<E>(self, value_str: &str) -> Result<Self::Value, E>
332        where
333            E: de::Error,
334        {
335            match value_str.parse::<i64>() {
336                Ok(value) => Ok(Duration::milliseconds(value)),
337                Err(err) => Err(E::custom(format!(
338                    "failed to parse integer from string: {}",
339                    err
340                ))),
341            }
342        }
343    }
344}
345
346pub(crate) mod duration_milliseconds_string_option {
347    use std::fmt;
348
349    use chrono::Duration;
350    use serde::{de, ser};
351
352    use super::duration_milliseconds_string;
353
354    pub(crate) fn serialize<S>(option: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
355    where
356        S: ser::Serializer,
357    {
358        match option {
359            Some(value) => duration_milliseconds_string::serialize(value, serializer),
360            None => serializer.serialize_none(),
361        }
362    }
363
364    pub fn deserialize<'de, D>(d: D) -> Result<Option<Duration>, D::Error>
365    where
366        D: de::Deserializer<'de>,
367    {
368        d.deserialize_option(DurationMillisecondsOptionVisitor)
369    }
370
371    pub struct DurationMillisecondsOptionVisitor;
372
373    impl<'de> de::Visitor<'de> for DurationMillisecondsOptionVisitor {
374        type Value = Option<Duration>;
375
376        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
377            formatter.write_str("optional duration (milliseconds as string)")
378        }
379
380        fn visit_none<E>(self) -> Result<Self::Value, E>
381        where
382            E: de::Error,
383        {
384            Ok(None)
385        }
386
387        fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
388        where
389            D: de::Deserializer<'de>,
390        {
391            let value = duration_milliseconds_string::deserialize(d)?;
392            Ok(Some(value))
393        }
394    }
395}
396
397///////////////////////////////////////////////////////////////////////////////
398
399pub(crate) mod session_ids_list {
400    use std::fmt;
401    use std::str::FromStr;
402
403    use serde::{de, ser};
404
405    use crate::mqtt::SessionId;
406
407    pub(crate) fn serialize<S>(session_ids: &[SessionId], serializer: S) -> Result<S::Ok, S::Error>
408    where
409        S: ser::Serializer,
410    {
411        let session_ids_str = session_ids
412            .iter()
413            .map(|id| id.to_string())
414            .collect::<Vec<String>>()
415            .join(" ");
416
417        serializer.serialize_str(&session_ids_str)
418    }
419
420    pub fn deserialize<'de, D>(d: D) -> Result<Vec<SessionId>, D::Error>
421    where
422        D: de::Deserializer<'de>,
423    {
424        d.deserialize_str(SessionIdListVisitor)
425    }
426
427    pub struct SessionIdListVisitor;
428
429    impl<'de> de::Visitor<'de> for SessionIdListVisitor {
430        type Value = Vec<SessionId>;
431
432        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
433            formatter.write_str("session id list (whitespace separated)")
434        }
435
436        fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
437        where
438            E: de::Error,
439        {
440            let mut session_ids = vec![];
441
442            for session_id_str in s.split(' ') {
443                match SessionId::from_str(session_id_str) {
444                    Ok(session_id) => session_ids.push(session_id),
445                    Err(err) => {
446                        return Err(E::custom(format!(
447                            "failed to parse SessionId from string: {}",
448                            err
449                        )))
450                    }
451                }
452            }
453
454            Ok(session_ids)
455        }
456    }
457}
458
459impl ser::Serialize for TrackingId {
460    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
461    where
462        S: ser::Serializer,
463    {
464        serializer.serialize_str(&self.to_string())
465    }
466}
467
468impl<'de> de::Deserialize<'de> for TrackingId {
469    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
470    where
471        D: de::Deserializer<'de>,
472    {
473        struct TrackingIdVisitor;
474
475        impl<'de> de::Visitor<'de> for TrackingIdVisitor {
476            type Value = TrackingId;
477
478            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
479                formatter.write_str("struct TrackingId")
480            }
481
482            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
483            where
484                E: de::Error,
485            {
486                use std::str::FromStr;
487
488                TrackingId::from_str(v)
489                    .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self))
490            }
491        }
492
493        deserializer.deserialize_str(TrackingIdVisitor)
494    }
495}