human_units/
size_serde.rs1use 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}