human_units/
size_serde.rs

1use core::fmt::Formatter;
2use core::fmt::Write;
3
4use crate::Buffer;
5use crate::Size;
6
7impl serde::Serialize for Size {
8    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
9    where
10        S: serde::Serializer,
11    {
12        let mut buf = Buffer::<{ Size::MAX_STRING_LEN }>::new();
13        let _ = write!(&mut buf, "{self}");
14        s.serialize_str(unsafe { core::str::from_utf8_unchecked(buf.as_slice()) })
15    }
16}
17
18impl<'a> serde::Deserialize<'a> for Size {
19    fn deserialize<D>(d: D) -> Result<Self, D::Error>
20    where
21        D: serde::Deserializer<'a>,
22    {
23        d.deserialize_str(SizeVisitor)
24    }
25}
26
27struct SizeVisitor;
28
29impl<'a> serde::de::Visitor<'a> for SizeVisitor {
30    type Value = Size;
31
32    fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
33        write!(formatter, "a string obtained by `Size::to_string`")
34    }
35
36    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
37    where
38        E: serde::de::Error,
39    {
40        value.parse().map_err(|_| E::custom("invalid size"))
41    }
42}
43
44#[cfg(all(test, feature = "std"))]
45mod tests {
46
47    use arbtest::arbtest;
48
49    use super::*;
50
51    #[test]
52    fn test_serde_io() {
53        assert_eq!("\"1k\"", serde_json::to_string(&Size(1024)).unwrap());
54        assert_eq!(Size(1024), serde_json::from_str("\"1k\"").unwrap());
55        assert_eq!(Size(1024), serde_yaml::from_str("1024").unwrap());
56    }
57
58    #[test]
59    fn test_max_string_len() {
60        let string = format!("{}", Size(u64::MAX));
61        assert_eq!(Size::MAX_STRING_LEN, string.len());
62    }
63
64    #[test]
65    fn test_serde_json() {
66        arbtest(|u| {
67            let expected: Size = u.arbitrary()?;
68            let string = serde_json::to_string(&expected).unwrap();
69            let actual = serde_json::from_str(&string).unwrap();
70            assert_eq!(expected, actual);
71            Ok(())
72        });
73    }
74
75    #[test]
76    fn test_serde_yaml() {
77        arbtest(|u| {
78            let expected: Size = u.arbitrary()?;
79            let string = serde_yaml::to_string(&expected).unwrap();
80            let actual = serde_yaml::from_str(&string).unwrap();
81            assert_eq!(expected, actual);
82            Ok(())
83        });
84    }
85
86    #[test]
87    fn test_serde_toml() {
88        arbtest(|u| {
89            let expected: SizeWrapper = u.arbitrary()?;
90            let string = toml::to_string(&expected).unwrap();
91            let actual = toml::from_str(&string).unwrap();
92            assert_eq!(expected, actual);
93            Ok(())
94        });
95    }
96
97    #[derive(
98        serde::Serialize, serde::Deserialize, arbitrary::Arbitrary, Debug, PartialEq, Eq, Clone,
99    )]
100    struct SizeWrapper {
101        size: Size,
102    }
103}