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