size_ser/
lib.rs

1//! Seralizer for `serde` to compute a lower bound for the size of any type that is `Serialize`.
2use std::{fmt::Error, mem::size_of};
3
4use paste::paste;
5use serde::{ser, Serialize};
6
7type Result<T> = std::result::Result<T, Error>;
8
9pub struct Serializer {
10    output: usize,
11}
12
13/// Computes a lower bound for the size of T.
14pub fn to_size<T>(value: &T) -> Result<usize>
15where
16    T: Serialize,
17{
18    let mut serializer = Serializer { output: 0 };
19    value.serialize(&mut serializer)?;
20    Ok(serializer.output)
21}
22
23macro_rules! ser {
24    ($($ty:ty),*) => {
25        $(
26        paste! {
27            fn [<serialize_ $ty>](self, _: $ty) -> Result<()> {
28                self.output += size_of::<$ty>();
29                Ok(())
30            }
31        }
32        )*
33    };
34}
35
36impl<'a> ser::Serializer for &'a mut Serializer {
37    type Ok = ();
38
39    type Error = Error;
40
41    type SerializeSeq = Self;
42    type SerializeTuple = Self;
43    type SerializeTupleStruct = Self;
44    type SerializeTupleVariant = Self;
45    type SerializeMap = Self;
46    type SerializeStruct = Self;
47    type SerializeStructVariant = Self;
48
49    ser!(bool, i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, char);
50
51    fn serialize_str(self, v: &str) -> Result<()> {
52        self.output += v.len();
53        Ok(())
54    }
55
56    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
57        self.output += v.len();
58        Ok(())
59    }
60
61    fn serialize_none(self) -> Result<()> {
62        Ok(())
63    }
64
65    fn serialize_some<T>(self, value: &T) -> Result<()>
66    where
67        T: ?Sized + Serialize,
68    {
69        value.serialize(self)
70    }
71
72    fn serialize_unit(self) -> Result<()> {
73        Ok(())
74    }
75
76    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
77        self.serialize_unit()
78    }
79
80    fn serialize_unit_variant(
81        self,
82        _name: &'static str,
83        _variant_index: u32,
84        _variant: &'static str,
85    ) -> Result<()> {
86        Ok(())
87    }
88
89    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
90    where
91        T: ?Sized + Serialize,
92    {
93        value.serialize(self)
94    }
95
96    fn serialize_newtype_variant<T>(
97        self,
98        _name: &'static str,
99        _variant_index: u32,
100        _variant: &'static str,
101        value: &T,
102    ) -> Result<()>
103    where
104        T: ?Sized + Serialize,
105    {
106        value.serialize(&mut *self)?;
107        Ok(())
108    }
109
110    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
111        Ok(self)
112    }
113
114    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
115        Ok(self)
116    }
117
118    fn serialize_tuple_struct(
119        self,
120        _name: &'static str,
121        _len: usize,
122    ) -> Result<Self::SerializeTupleStruct> {
123        Ok(self)
124    }
125
126    fn serialize_tuple_variant(
127        self,
128        _name: &'static str,
129        _variant_index: u32,
130        _variant: &'static str,
131        _len: usize,
132    ) -> Result<Self::SerializeTupleVariant> {
133        Ok(self)
134    }
135
136    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
137        Ok(self)
138    }
139
140    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
141        Ok(self)
142    }
143
144    fn serialize_struct_variant(
145        self,
146        _name: &'static str,
147        _variant_index: u32,
148        _variant: &'static str,
149        _len: usize,
150    ) -> Result<Self::SerializeStructVariant> {
151        Ok(self)
152    }
153}
154
155impl<'a> ser::SerializeSeq for &'a mut Serializer {
156    type Ok = ();
157    type Error = Error;
158
159    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
160    where
161        T: ?Sized + Serialize,
162    {
163        value.serialize(&mut **self)
164    }
165
166    fn end(self) -> Result<()> {
167        Ok(())
168    }
169}
170
171impl<'a> ser::SerializeTuple for &'a mut Serializer {
172    type Ok = ();
173    type Error = Error;
174
175    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
176    where
177        T: ?Sized + Serialize,
178    {
179        value.serialize(&mut **self)
180    }
181
182    fn end(self) -> Result<()> {
183        Ok(())
184    }
185}
186
187impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
188    type Ok = ();
189    type Error = Error;
190
191    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
192    where
193        T: ?Sized + Serialize,
194    {
195        value.serialize(&mut **self)
196    }
197
198    fn end(self) -> Result<()> {
199        Ok(())
200    }
201}
202
203impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
204    type Ok = ();
205    type Error = Error;
206
207    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
208    where
209        T: ?Sized + Serialize,
210    {
211        value.serialize(&mut **self)
212    }
213
214    fn end(self) -> Result<()> {
215        Ok(())
216    }
217}
218
219impl<'a> ser::SerializeMap for &'a mut Serializer {
220    type Ok = ();
221    type Error = Error;
222
223    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
224    where
225        T: ?Sized + Serialize,
226    {
227        key.serialize(&mut **self)
228    }
229
230    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
231    where
232        T: ?Sized + Serialize,
233    {
234        value.serialize(&mut **self)
235    }
236
237    fn end(self) -> Result<()> {
238        Ok(())
239    }
240}
241
242impl<'a> ser::SerializeStruct for &'a mut Serializer {
243    type Ok = ();
244    type Error = Error;
245
246    fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
247    where
248        T: ?Sized + Serialize,
249    {
250        value.serialize(&mut **self)
251    }
252
253    fn end(self) -> Result<()> {
254        Ok(())
255    }
256}
257
258impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
259    type Ok = ();
260    type Error = Error;
261
262    fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
263    where
264        T: ?Sized + Serialize,
265    {
266        value.serialize(&mut **self)
267    }
268
269    fn end(self) -> Result<()> {
270        Ok(())
271    }
272}
273
274#[cfg(test)]
275mod test {
276    use super::*;
277
278    use std::collections::HashMap;
279
280    use serde::Serialize;
281
282    #[test]
283    fn vec_u8_works() {
284        let v = vec![1u8, 2, 3, 4, 5];
285
286        let got = to_size(&v).unwrap();
287
288        assert_eq!(got, v.len() * size_of::<u8>());
289    }
290
291    #[test]
292    fn vec_u64_works() {
293        let v = vec![1u64, 2, 3, 4, 5];
294
295        let got = to_size(&v).unwrap();
296
297        assert_eq!(got, v.len() * size_of::<u64>());
298    }
299
300    #[test]
301    fn struct_works() {
302        #[derive(Serialize)]
303        struct Value {
304            a: f64,
305            b: String,
306        }
307
308        let v = Value {
309            a: 23.,
310            b: "cool".to_string(),
311        };
312        let got = to_size(&v).unwrap();
313
314        let want = size_of::<f64>() + "cool".len();
315        assert_eq!(got, want);
316    }
317
318    #[test]
319    fn map_works() {
320        let mut m: HashMap<&str, u128> = HashMap::new();
321        m.insert("wow", 23);
322        m.insert("ok", 9);
323
324        let got = to_size(&m).unwrap();
325
326        let want = size_of::<u128>() + "wow".len() + size_of::<u128>() + "ok".len();
327        assert_eq!(got, want);
328    }
329
330    #[test]
331    fn map_u128_struct_works() {
332        #[derive(Serialize)]
333        struct Value {
334            a: f64,
335            b: String,
336        }
337
338        let mut m: HashMap<u128, Value> = HashMap::new();
339        m.insert(
340            5,
341            Value {
342                a: 42.,
343                b: "Hello world".to_string(),
344            },
345        );
346        m.insert(
347            8,
348            Value {
349                a: 24.,
350                b: "world".to_string(),
351            },
352        );
353
354        let got = to_size(&m).unwrap();
355
356        let want = size_of::<u128>()
357            + size_of::<f64>()
358            + "Hello world".len()
359            + size_of::<u128>()
360            + size_of::<f64>()
361            + "world".len();
362        assert_eq!(got, want);
363    }
364}