chrono/naive/time/
serde.rs

1use super::NaiveTime;
2use core::fmt;
3use serde::{de, ser};
4
5// TODO not very optimized for space (binary formats would want something better)
6// TODO round-trip for general leap seconds (not just those with second = 60)
7
8impl ser::Serialize for NaiveTime {
9    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10    where
11        S: ser::Serializer,
12    {
13        serializer.collect_str(&self)
14    }
15}
16
17struct NaiveTimeVisitor;
18
19impl<'de> de::Visitor<'de> for NaiveTimeVisitor {
20    type Value = NaiveTime;
21
22    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
23        formatter.write_str("a formatted time string")
24    }
25
26    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
27    where
28        E: de::Error,
29    {
30        value.parse().map_err(E::custom)
31    }
32}
33
34impl<'de> de::Deserialize<'de> for NaiveTime {
35    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36    where
37        D: de::Deserializer<'de>,
38    {
39        deserializer.deserialize_str(NaiveTimeVisitor)
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use crate::naive::time::{test_decodable_json, test_encodable_json};
46    use crate::NaiveTime;
47
48    #[test]
49    fn test_serde_serialize() {
50        test_encodable_json(serde_json::to_string);
51    }
52
53    #[test]
54    fn test_serde_deserialize() {
55        test_decodable_json(|input| serde_json::from_str(input));
56    }
57
58    #[test]
59    fn test_serde_bincode() {
60        // Bincode is relevant to test separately from JSON because
61        // it is not self-describing.
62        use bincode::{deserialize, serialize};
63
64        let t = NaiveTime::from_hms_nano_opt(3, 5, 7, 98765432).unwrap();
65        let encoded = serialize(&t).unwrap();
66        let decoded: NaiveTime = deserialize(&encoded).unwrap();
67        assert_eq!(t, decoded);
68    }
69}