serde_sibor/
ser.rs

1use crate::error::{Error, Result};
2
3/// A helper for serializing elements of a dynamically sized collection.
4pub struct CollectionSerializer<'a, W> {
5    remaining: usize,
6    ser: &'a mut Serializer<W>,
7}
8impl<'a, W> ::serde::ser::SerializeSeq for CollectionSerializer<'a, W>
9where
10    W: ::std::io::Write,
11{
12    type Ok = ();
13    type Error = Error;
14
15    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<Self::Ok>
16    where
17        T: serde::Serialize,
18    {
19        if self.remaining < 1 {
20            return Err(Error::Generic(
21                "tried to serialize too many elements in collection".into(),
22            ));
23        }
24        self.remaining -= 1;
25        value.serialize(&mut *self.ser)
26    }
27
28    fn end(self) -> Result<Self::Ok> {
29        Ok(())
30    }
31}
32
33/// A helper for serializing statically structured data such as
34/// tuples, structs, and fixed-length arrays.
35pub struct TupleSerializer<'a, W> {
36    ser: &'a mut Serializer<W>,
37}
38
39impl<'a, W> ::serde::ser::SerializeTuple for TupleSerializer<'a, W>
40where
41    W: ::std::io::Write,
42{
43    type Ok = ();
44    type Error = Error;
45
46    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<Self::Ok>
47    where
48        T: serde::Serialize,
49    {
50        value.serialize(&mut *self.ser)
51    }
52
53    fn end(self) -> Result<Self::Ok> {
54        Ok(())
55    }
56}
57
58impl<'a, W> ::serde::ser::SerializeTupleStruct for TupleSerializer<'a, W>
59where
60    W: ::std::io::Write,
61{
62    type Ok = ();
63    type Error = Error;
64
65    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<Self::Ok>
66    where
67        T: serde::Serialize,
68    {
69        value.serialize(&mut *self.ser)
70    }
71
72    fn end(self) -> Result<Self::Ok> {
73        Ok(())
74    }
75}
76
77impl<'a, W> ::serde::ser::SerializeTupleVariant for TupleSerializer<'a, W>
78where
79    W: ::std::io::Write,
80{
81    type Ok = ();
82    type Error = Error;
83
84    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<Self::Ok>
85    where
86        T: serde::Serialize,
87    {
88        value.serialize(&mut *self.ser)
89    }
90
91    fn end(self) -> Result<Self::Ok> {
92        Ok(())
93    }
94}
95
96impl<'a, W> ::serde::ser::SerializeStruct for TupleSerializer<'a, W>
97where
98    W: ::std::io::Write,
99{
100    type Ok = ();
101    type Error = Error;
102
103    fn serialize_field<T: ?Sized>(&mut self, _: &'static str, value: &T) -> Result<Self::Ok>
104    where
105        T: serde::Serialize,
106    {
107        value.serialize(&mut *self.ser)
108    }
109
110    fn end(self) -> Result<Self::Ok> {
111        Ok(())
112    }
113}
114
115impl<'a, W> ::serde::ser::SerializeStructVariant for TupleSerializer<'a, W>
116where
117    W: ::std::io::Write,
118{
119    type Ok = ();
120    type Error = Error;
121
122    fn serialize_field<T: ?Sized>(&mut self, _: &'static str, value: &T) -> Result<Self::Ok>
123    where
124        T: serde::Serialize,
125    {
126        value.serialize(&mut *self.ser)
127    }
128
129    fn end(self) -> Result<Self::Ok> {
130        Ok(())
131    }
132}
133
134/// A serializer that can serialize values to a writer.
135pub struct Serializer<W> {
136    writer: W,
137}
138
139impl<W> Serializer<W> {
140    /// Create a new serializer that writes to the given writer.
141    pub fn new(writer: W) -> Self {
142        Self { writer }
143    }
144}
145
146impl<W> Serializer<W>
147where
148    W: ::std::io::Write,
149{
150    /// Get the zigzag encoding of a signed integer.
151    pub fn zigzag(&self, v: i64) -> u64 {
152        let mut unsigned = (v as u64) << 1;
153        if v < 0 {
154            unsigned = !unsigned;
155        }
156        unsigned
157    }
158
159    /// Get the number of bytes required to encode an unsigned integer.
160    pub fn sizeof_uvarint(&self, v: &u64) -> Result<usize> {
161        let mut v = *v;
162        let mut size = 1usize;
163        while v >= 0x80 {
164            size += 1;
165            v >>= 7;
166        }
167        Ok(size)
168    }
169
170    /// Get the number of bytes required to encode a signed integer.
171    pub fn sizeof_varint(&self, v: &i64) -> Result<usize> {
172        let unsigned = self.zigzag(*v);
173        self.sizeof_uvarint(&unsigned)
174    }
175
176    /// Get the number of bytes required to encode a 64-bit floating point number.
177    pub fn sizeof_float(&self, v: &f64) -> Result<usize> {
178        return self.sizeof_uvarint(&v.to_bits());
179    }
180
181    /// Get the number of bytes required to encode a boolean.
182    pub fn sizeof_bool(&self, _: bool) -> Result<usize> {
183        Ok(1)
184    }
185
186    /// Get the number of bytes required to encode a string.
187    pub fn sizeof_string(&self, v: &str) -> Result<usize> {
188        self.sizeof_bytes(v.as_bytes())
189    }
190
191    /// Get the number of bytes required to encode a byte array.
192    pub fn sizeof_bytes(&self, v: &[u8]) -> Result<usize> {
193        let len64 = u64::try_from(v.len()).map_err(|e| Error::Generic(e.to_string()))?;
194        Self::combine_sizes([self.sizeof_uvarint(&len64)?, v.len()])
195    }
196
197    /// A helper method for writing the full and exact contents of a buffer
198    /// to the underlying writer.
199    fn write_exact(&mut self, buf: &[u8]) -> Result<()> {
200        self.writer.write_all(buf).map_err(Error::Io)
201    }
202
203    /// Write a single byte to the byte stream.
204    /// This is a special case that does not use variable-length encoding.
205    pub fn write_u8(&mut self, v: u8) -> Result<()> {
206        self.write_exact(&[v])
207    }
208
209    /// Write an unsigned 64-bit integer to the byte stream using variable-length encoding.
210    pub fn write_uvarint(&mut self, mut v: u64) -> Result<()> {
211        while v >= 0x80 {
212            self.write_u8((v & 0x7f) as u8 | 0x80)?;
213            v >>= 7;
214        }
215        self.write_u8((v & 0x7f) as u8)?;
216        Ok(())
217    }
218
219    /// Write a signed 64-bit integer to the byte stream using variable-length zigzag encoding.
220    pub fn write_ivarint(&mut self, v: i64) -> Result<()> {
221        let unsigned = self.zigzag(v);
222        self.write_uvarint(unsigned)
223    }
224
225    /// Write a 64-bit floating point number to the byte stream.
226    /// The bits of the floating point number are written as an unsigned integer.
227    pub fn write_float(&mut self, v: f64) -> Result<()> {
228        self.write_uvarint(v.to_bits())
229    }
230
231    /// Write a boolean to the byte stream.
232    pub fn write_bool(&mut self, v: bool) -> Result<()> {
233        self.write_u8(if v { 1 } else { 0 })
234    }
235
236    /// Write a byte string to the byte stream.
237    /// First, the length us written as a variable-length unsigned integer.
238    /// Then, the contents of the byte string are written exactly as-is.
239    pub fn write_bytes(&mut self, v: &[u8]) -> Result<()> {
240        let len64 = u64::try_from(v.len()).map_err(|e| Error::Generic(e.to_string()))?;
241        self.write_uvarint(len64)?;
242        self.write_exact(v)?;
243        Ok(())
244    }
245
246    /// Write a utf8-encoded string to the byte stream.
247    /// First, the length us written as a variable-length unsigned integer.
248    /// Then, the contents of the string are written exactly as-is.
249    pub fn write_string(&mut self, v: &str) -> Result<()> {
250        self.write_bytes(v.as_bytes())
251    }
252
253    fn combine_sizes(sizes: impl IntoIterator<Item = usize>) -> Result<usize> {
254        sizes
255            .into_iter()
256            .fold(Some(0), |agg, v| Some(agg? + v))
257            .ok_or_else(|| Error::Generic("size too large".into()))
258    }
259}
260
261impl<'a, W> ::serde::ser::Serializer for &'a mut Serializer<W>
262where
263    W: ::std::io::Write,
264{
265    type Error = Error;
266    type Ok = ();
267
268    type SerializeSeq = CollectionSerializer<'a, W>;
269
270    type SerializeTuple = TupleSerializer<'a, W>;
271
272    type SerializeTupleStruct = TupleSerializer<'a, W>;
273
274    type SerializeTupleVariant = TupleSerializer<'a, W>;
275
276    type SerializeMap = ::serde::ser::Impossible<(), Error>;
277
278    type SerializeStruct = TupleSerializer<'a, W>;
279
280    type SerializeStructVariant = TupleSerializer<'a, W>;
281
282    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
283        self.write_bool(v)
284    }
285
286    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
287        self.write_ivarint(v as i64)
288    }
289
290    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
291        self.write_ivarint(v as i64)
292    }
293
294    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
295        self.write_ivarint(v as i64)
296    }
297
298    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
299        self.write_ivarint(v)
300    }
301
302    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
303        self.write_uvarint(v as u64)
304    }
305
306    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
307        self.write_uvarint(v as u64)
308    }
309
310    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
311        self.write_uvarint(v as u64)
312    }
313
314    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
315        self.write_uvarint(v)
316    }
317
318    fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
319        self.write_float(v as f64)
320    }
321
322    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
323        self.write_float(v)
324    }
325
326    fn serialize_char(self, _: char) -> Result<Self::Ok> {
327        Err(Error::Unsupported("serialize char".into()))
328    }
329
330    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
331        self.write_string(v)
332    }
333
334    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
335        self.write_bytes(v)
336    }
337
338    fn serialize_none(self) -> Result<Self::Ok> {
339        Err(Error::Unsupported("serialize option".into()))
340    }
341
342    fn serialize_some<T: ?Sized>(self, _: &T) -> Result<Self::Ok>
343    where
344        T: serde::Serialize,
345    {
346        Err(Error::Unsupported("serialize option".into()))
347    }
348
349    fn serialize_unit(self) -> Result<Self::Ok> {
350        Ok(())
351    }
352
353    fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok> {
354        Ok(())
355    }
356
357    fn serialize_unit_variant(
358        self,
359        _: &'static str,
360        variant_index: u32,
361        _: &'static str,
362    ) -> Result<Self::Ok> {
363        self.write_uvarint(variant_index as u64)
364    }
365
366    fn serialize_newtype_struct<T: ?Sized>(self, _: &'static str, value: &T) -> Result<Self::Ok>
367    where
368        T: serde::Serialize,
369    {
370        value.serialize(self)
371    }
372
373    fn serialize_newtype_variant<T: ?Sized>(
374        self,
375        _: &'static str,
376        variant_index: u32,
377        _: &'static str,
378        value: &T,
379    ) -> Result<Self::Ok>
380    where
381        T: serde::Serialize,
382    {
383        self.write_uvarint(variant_index as u64)?;
384        value.serialize(self)
385    }
386
387    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
388        match len {
389            Some(remaining) => {
390                let len64 = u64::try_from(remaining).map_err(|e| Error::Generic(e.to_string()))?;
391                self.write_uvarint(len64)?;
392                Ok(CollectionSerializer {
393                    remaining,
394                    ser: self,
395                })
396            }
397            None => Err(Error::Unsupported("serialize seq (unsized)".into())),
398        }
399    }
400
401    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
402        Ok(TupleSerializer { ser: self })
403    }
404
405    fn serialize_tuple_struct(
406        self,
407        _: &'static str,
408        _: usize,
409    ) -> Result<Self::SerializeTupleStruct> {
410        Ok(TupleSerializer { ser: self })
411    }
412
413    fn serialize_tuple_variant(
414        self,
415        _: &'static str,
416        variant_index: u32,
417        _: &'static str,
418        _: usize,
419    ) -> Result<Self::SerializeTupleVariant> {
420        self.write_uvarint(variant_index as u64)?;
421        Ok(TupleSerializer { ser: self })
422    }
423
424    fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
425        Err(Error::Unsupported("serialize map".into()))
426    }
427
428    fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
429        Ok(TupleSerializer { ser: self })
430    }
431
432    fn serialize_struct_variant(
433        self,
434        _: &'static str,
435        variant_index: u32,
436        _: &'static str,
437        _: usize,
438    ) -> Result<Self::SerializeStructVariant> {
439        self.write_uvarint(variant_index as u64)?;
440        Ok(TupleSerializer { ser: self })
441    }
442}