ruma_common/serde/duration/
opt_ms.rs
1use std::time::Duration;
7
8use js_int::UInt;
9use serde::{
10 de::{Deserialize, Deserializer},
11 ser::{Error, Serialize, Serializer},
12};
13
14pub fn serialize<S>(opt_duration: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
19where
20 S: Serializer,
21{
22 match opt_duration {
23 Some(duration) => match UInt::try_from(duration.as_millis()) {
24 Ok(uint) => uint.serialize(serializer),
25 Err(err) => Err(S::Error::custom(err)),
26 },
27 None => serializer.serialize_none(),
28 }
29}
30
31pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
36where
37 D: Deserializer<'de>,
38{
39 Ok(Option::<UInt>::deserialize(deserializer)?
40 .map(|millis| Duration::from_millis(millis.into())))
41}
42
43#[cfg(test)]
44mod tests {
45 use std::time::Duration;
46
47 use serde::{Deserialize, Serialize};
48 use serde_json::json;
49
50 #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
51 struct DurationTest {
52 #[serde(with = "super", default, skip_serializing_if = "Option::is_none")]
53 timeout: Option<Duration>,
54 }
55
56 #[test]
57 fn deserialize_some() {
58 let json = json!({ "timeout": 3000 });
59
60 assert_eq!(
61 serde_json::from_value::<DurationTest>(json).unwrap(),
62 DurationTest { timeout: Some(Duration::from_millis(3000)) },
63 );
64 }
65
66 #[test]
67 fn deserialize_none_by_absence() {
68 let json = json!({});
69
70 assert_eq!(
71 serde_json::from_value::<DurationTest>(json).unwrap(),
72 DurationTest { timeout: None },
73 );
74 }
75
76 #[test]
77 fn deserialize_none_by_null() {
78 let json = json!({ "timeout": null });
79
80 assert_eq!(
81 serde_json::from_value::<DurationTest>(json).unwrap(),
82 DurationTest { timeout: None },
83 );
84 }
85
86 #[test]
87 fn serialize_some() {
88 let request = DurationTest { timeout: Some(Duration::new(2, 0)) };
89 assert_eq!(serde_json::to_value(request).unwrap(), json!({ "timeout": 2000 }));
90 }
91
92 #[test]
93 fn serialize_none() {
94 let request = DurationTest { timeout: None };
95 assert_eq!(serde_json::to_value(request).unwrap(), json!({}));
96 }
97}