1use std::marker::PhantomData;
5
6use byte_unit::Byte;
7use serde::{Deserialize, Serialize, Serializer};
8
9pub fn deserialize<'a, T, D>(der: D) -> Result<T, D::Error>
14where
15 D: serde::Deserializer<'a>,
16 T: TryFrom<Deser<'a, D>, Error = D::Error>,
17{
18 T::try_from(Deser(der, PhantomData))
19}
20
21pub fn serialize<T, S>(val: &T, ser: S) -> Result<S::Ok, S::Error>
26where
27 S: Serializer,
28 for<'a> Ser<&'a T>: Serialize,
29{
30 Ser::from(val).serialize(ser)
31}
32
33#[derive(Debug)]
36pub struct Deser<'a, D>(D, PhantomData<&'a ()>);
37
38impl<'a, D> TryFrom<Deser<'a, D>> for u64
39where
40 D: serde::Deserializer<'a>,
41{
42 type Error = D::Error;
43
44 fn try_from(value: Deser<'a, D>) -> Result<Self, Self::Error> {
45 let byte = Byte::deserialize(value.0)?;
46 Ok(byte.as_u64())
47 }
48}
49
50impl<'a, D> TryFrom<Deser<'a, D>> for Option<u64>
51where
52 D: serde::Deserializer<'a>,
53{
54 type Error = D::Error;
55
56 fn try_from(value: Deser<'a, D>) -> Result<Self, Self::Error> {
57 let byte = Option::<Byte>::deserialize(value.0)?;
58 Ok(byte.map(Byte::as_u64))
59 }
60}
61
62#[derive(Debug)]
65pub struct Ser<T>(T);
66
67impl Serialize for Ser<&u64> {
68 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69 where
70 S: Serializer,
71 {
72 Byte::from_u64(*self.0).serialize(serializer)
73 }
74}
75
76impl Serialize for Ser<&Option<u64>> {
77 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78 where
79 S: Serializer,
80 {
81 self.0.map(Byte::from_u64).serialize(serializer)
82 }
83}
84
85impl<T> From<T> for Ser<T> {
86 fn from(value: T) -> Self {
87 Self(value)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use serde::{Deserialize, Serialize};
94 use serde_json::json;
95
96 #[derive(Debug, Serialize, Deserialize)]
97 struct Values {
98 #[serde(with = "super")]
99 size: u64,
100 }
101
102 #[test]
103 fn test_deserialize_byte() {
104 let test_cases = [
105 (json!({ "size": "1024kB" }), 1_024_000),
106 (json!({ "size": "1024MiB" }), 1_073_741_824),
107 (json!({ "size": "1kB" }), 1000),
108 (json!({ "size": "1kiB" }), 1024),
109 (json!({ "size": "1" }), 1),
110 ];
111
112 for (json, expected) in test_cases {
113 let values: Values = serde_json::from_value(json).unwrap();
114 assert_eq!(values.size, expected);
115 }
116 }
117
118 #[test]
119 fn test_serialize_byte() {
120 let test_cases = [
121 (Values { size: 1_024_000 }, json!({ "size": "1.024 MB" })),
122 (
123 Values {
124 size: 1_073_741_824,
125 },
126 json!({ "size": "1 GiB" }),
127 ),
128 (Values { size: 1000 }, json!({ "size": "1 KB" })),
129 (Values { size: 1024 }, json!({ "size": "1 KiB" })),
130 (Values { size: 1 }, json!({ "size": "1 B" })),
131 ];
132
133 for (value, expected) in test_cases {
134 let json = json!(value);
135 assert_eq!(json, expected);
136 }
137 }
138}