bcs/
ser.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::error::{Error, Result};
5use serde::{ser, Serialize};
6
7/// Serialize the given data structure as a `Vec<u8>` of BCS.
8///
9/// Serialization can fail if `T`'s implementation of `Serialize` decides to
10/// fail, if `T` contains sequences which are longer than `MAX_SEQUENCE_LENGTH`,
11/// or if `T` attempts to serialize an unsupported datatype such as a f32,
12/// f64, or char.
13///
14/// # Examples
15///
16/// ```
17/// use bcs::to_bytes;
18/// use serde::Serialize;
19///
20/// #[derive(Serialize)]
21/// struct Ip([u8; 4]);
22///
23/// #[derive(Serialize)]
24/// struct Port(u16);
25///
26/// #[derive(Serialize)]
27/// struct Service {
28///     ip: Ip,
29///     port: Vec<Port>,
30///     connection_max: Option<u32>,
31///     enabled: bool,
32/// }
33///
34/// let service = Service {
35///     ip: Ip([192, 168, 1, 1]),
36///     port: vec![Port(8001), Port(8002), Port(8003)],
37///     connection_max: Some(5000),
38///     enabled: false,
39/// };
40///
41/// let bytes = to_bytes(&service).unwrap();
42/// let expected = vec![
43///     0xc0, 0xa8, 0x01, 0x01, 0x03, 0x41, 0x1f, 0x42,
44///     0x1f, 0x43, 0x1f, 0x01, 0x88, 0x13, 0x00, 0x00,
45///     0x00,
46/// ];
47/// assert_eq!(bytes, expected);
48/// ```
49pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
50where
51    T: ?Sized + Serialize,
52{
53    let mut output = Vec::new();
54    serialize_into(&mut output, value)?;
55    Ok(output)
56}
57
58/// Same as `to_bytes` but use `limit` as max container depth instead of MAX_CONTAINER_DEPTH
59/// Note that `limit` has to be lower than MAX_CONTAINER_DEPTH
60pub fn to_bytes_with_limit<T>(value: &T, limit: usize) -> Result<Vec<u8>>
61where
62    T: ?Sized + Serialize,
63{
64    if limit > crate::MAX_CONTAINER_DEPTH {
65        return Err(Error::NotSupported("limit exceeds the max allowed depth"));
66    }
67    let mut output = Vec::new();
68    serialize_into_with_limit(&mut output, value, limit)?;
69    Ok(output)
70}
71
72/// Same as `to_bytes` but write directly into an `std::io::Write` object.
73pub fn serialize_into<W, T>(write: &mut W, value: &T) -> Result<()>
74where
75    W: ?Sized + std::io::Write,
76    T: ?Sized + Serialize,
77{
78    let serializer = Serializer::new(write, crate::MAX_CONTAINER_DEPTH);
79    value.serialize(serializer)
80}
81
82/// Same as `serialize_into` but use `limit` as max container depth instead of MAX_CONTAINER_DEPTH
83/// Note that `limit` has to be lower than MAX_CONTAINER_DEPTH
84pub fn serialize_into_with_limit<W, T>(write: &mut W, value: &T, limit: usize) -> Result<()>
85where
86    W: ?Sized + std::io::Write,
87    T: ?Sized + Serialize,
88{
89    if limit > crate::MAX_CONTAINER_DEPTH {
90        return Err(Error::NotSupported("limit exceeds the max allowed depth"));
91    }
92    let serializer = Serializer::new(write, limit);
93    value.serialize(serializer)
94}
95
96struct WriteCounter(usize);
97
98impl std::io::Write for WriteCounter {
99    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
100        let len = buf.len();
101        self.0 = self.0.checked_add(len).ok_or_else(|| {
102            std::io::Error::new(std::io::ErrorKind::Other, "WriteCounter reached max value")
103        })?;
104        Ok(len)
105    }
106
107    fn flush(&mut self) -> std::io::Result<()> {
108        Ok(())
109    }
110}
111
112/// Same as `to_bytes` but only return the size of the serialized bytes.
113pub fn serialized_size<T>(value: &T) -> Result<usize>
114where
115    T: ?Sized + Serialize,
116{
117    let mut counter = WriteCounter(0);
118    serialize_into(&mut counter, value)?;
119    Ok(counter.0)
120}
121
122/// Same as `serialized_size` but use `limit` as max container depth instead of MAX_CONTAINER_DEPTH
123/// Note that `limit` has to be lower than MAX_CONTAINER_DEPTH
124pub fn serialized_size_with_limit<T>(value: &T, limit: usize) -> Result<usize>
125where
126    T: ?Sized + Serialize,
127{
128    if limit > crate::MAX_CONTAINER_DEPTH {
129        return Err(Error::NotSupported("limit exceeds the max allowed depth"));
130    }
131    let mut counter = WriteCounter(0);
132    serialize_into_with_limit(&mut counter, value, limit)?;
133    Ok(counter.0)
134}
135
136pub fn is_human_readable() -> bool {
137    let mut output = Vec::new();
138    let serializer = Serializer::new(&mut output, crate::MAX_CONTAINER_DEPTH);
139    ser::Serializer::is_human_readable(&serializer)
140}
141
142/// Serialization implementation for BCS
143struct Serializer<'a, W: ?Sized> {
144    output: &'a mut W,
145    max_remaining_depth: usize,
146}
147
148impl<'a, W> Serializer<'a, W>
149where
150    W: ?Sized + std::io::Write,
151{
152    /// Creates a new `Serializer` which will emit BCS.
153    fn new(output: &'a mut W, max_remaining_depth: usize) -> Self {
154        Self {
155            output,
156            max_remaining_depth,
157        }
158    }
159
160    fn output_u32_as_uleb128(&mut self, mut value: u32) -> Result<()> {
161        while value >= 0x80 {
162            // Write 7 (lowest) bits of data and set the 8th bit to 1.
163            let byte = (value & 0x7f) as u8;
164            self.output.write_all(&[byte | 0x80])?;
165            value >>= 7;
166        }
167        // Write the remaining bits of data and set the highest bit to 0.
168        self.output.write_all(&[value as u8])?;
169        Ok(())
170    }
171
172    fn output_variant_index(&mut self, v: u32) -> Result<()> {
173        self.output_u32_as_uleb128(v)
174    }
175
176    /// Serialize a sequence length as a u32.
177    fn output_seq_len(&mut self, len: usize) -> Result<()> {
178        if len > crate::MAX_SEQUENCE_LENGTH {
179            return Err(Error::ExceededMaxLen(len));
180        }
181        self.output_u32_as_uleb128(len as u32)
182    }
183
184    fn enter_named_container(&mut self, name: &'static str) -> Result<()> {
185        if self.max_remaining_depth == 0 {
186            return Err(Error::ExceededContainerDepthLimit(name));
187        }
188        self.max_remaining_depth -= 1;
189        Ok(())
190    }
191}
192
193impl<'a, W> ser::Serializer for Serializer<'a, W>
194where
195    W: ?Sized + std::io::Write,
196{
197    type Ok = ();
198    type Error = Error;
199    type SerializeSeq = Self;
200    type SerializeTuple = Self;
201    type SerializeTupleStruct = Self;
202    type SerializeTupleVariant = Self;
203    type SerializeMap = MapSerializer<'a, W>;
204    type SerializeStruct = Self;
205    type SerializeStructVariant = Self;
206
207    fn serialize_bool(self, v: bool) -> Result<()> {
208        self.serialize_u8(v.into())
209    }
210
211    fn serialize_i8(self, v: i8) -> Result<()> {
212        self.serialize_u8(v as u8)
213    }
214
215    fn serialize_i16(self, v: i16) -> Result<()> {
216        self.serialize_u16(v as u16)
217    }
218
219    fn serialize_i32(self, v: i32) -> Result<()> {
220        self.serialize_u32(v as u32)
221    }
222
223    fn serialize_i64(self, v: i64) -> Result<()> {
224        self.serialize_u64(v as u64)
225    }
226
227    fn serialize_i128(self, v: i128) -> Result<()> {
228        self.serialize_u128(v as u128)
229    }
230
231    fn serialize_u8(self, v: u8) -> Result<()> {
232        self.output.write_all(&[v])?;
233        Ok(())
234    }
235
236    fn serialize_u16(self, v: u16) -> Result<()> {
237        self.output.write_all(&v.to_le_bytes())?;
238        Ok(())
239    }
240
241    fn serialize_u32(self, v: u32) -> Result<()> {
242        self.output.write_all(&v.to_le_bytes())?;
243        Ok(())
244    }
245
246    fn serialize_u64(self, v: u64) -> Result<()> {
247        self.output.write_all(&v.to_le_bytes())?;
248        Ok(())
249    }
250
251    fn serialize_u128(self, v: u128) -> Result<()> {
252        self.output.write_all(&v.to_le_bytes())?;
253        Ok(())
254    }
255
256    fn serialize_f32(self, _v: f32) -> Result<()> {
257        Err(Error::NotSupported("serialize_f32"))
258    }
259
260    fn serialize_f64(self, _v: f64) -> Result<()> {
261        Err(Error::NotSupported("serialize_f64"))
262    }
263
264    fn serialize_char(self, _v: char) -> Result<()> {
265        Err(Error::NotSupported("serialize_char"))
266    }
267
268    // Just serialize the string as a raw byte array
269    fn serialize_str(self, v: &str) -> Result<()> {
270        self.serialize_bytes(v.as_bytes())
271    }
272
273    // Serialize a byte array as an array of bytes.
274    fn serialize_bytes(mut self, v: &[u8]) -> Result<()> {
275        self.output_seq_len(v.len())?;
276        self.output.write_all(v)?;
277        Ok(())
278    }
279
280    // An absent optional is represented as `00`
281    fn serialize_none(self) -> Result<()> {
282        self.serialize_u8(0)
283    }
284
285    // A present optional is represented as `01` followed by the serialized value
286    fn serialize_some<T>(self, value: &T) -> Result<()>
287    where
288        T: ?Sized + Serialize,
289    {
290        self.output.write_all(&[1])?;
291        value.serialize(self)
292    }
293
294    fn serialize_unit(self) -> Result<()> {
295        Ok(())
296    }
297
298    fn serialize_unit_struct(mut self, name: &'static str) -> Result<()> {
299        self.enter_named_container(name)?;
300        self.serialize_unit()
301    }
302
303    fn serialize_unit_variant(
304        mut self,
305        name: &'static str,
306        variant_index: u32,
307        _variant: &'static str,
308    ) -> Result<()> {
309        self.enter_named_container(name)?;
310        self.output_variant_index(variant_index)
311    }
312
313    fn serialize_newtype_struct<T>(mut self, name: &'static str, value: &T) -> Result<()>
314    where
315        T: ?Sized + Serialize,
316    {
317        self.enter_named_container(name)?;
318        value.serialize(self)
319    }
320
321    fn serialize_newtype_variant<T>(
322        mut self,
323        name: &'static str,
324        variant_index: u32,
325        _variant: &'static str,
326        value: &T,
327    ) -> Result<()>
328    where
329        T: ?Sized + Serialize,
330    {
331        self.enter_named_container(name)?;
332        self.output_variant_index(variant_index)?;
333        value.serialize(self)
334    }
335
336    // The start of the sequence, each value, and the end are three separate
337    // method calls. This one is responsible only for serializing the start,
338    // which for BCS is either nothing for fixed structures or for variable
339    // length structures, the length encoded as a u32.
340    fn serialize_seq(mut self, len: Option<usize>) -> Result<Self::SerializeSeq> {
341        if let Some(len) = len {
342            self.output_seq_len(len)?;
343            Ok(self)
344        } else {
345            Err(Error::MissingLen)
346        }
347    }
348
349    // Tuples are fixed sized structs so we don't need to encode the length
350    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
351        Ok(self)
352    }
353
354    fn serialize_tuple_struct(
355        mut self,
356        name: &'static str,
357        _len: usize,
358    ) -> Result<Self::SerializeTupleStruct> {
359        self.enter_named_container(name)?;
360        Ok(self)
361    }
362
363    fn serialize_tuple_variant(
364        mut self,
365        name: &'static str,
366        variant_index: u32,
367        _variant: &'static str,
368        _len: usize,
369    ) -> Result<Self::SerializeTupleVariant> {
370        self.enter_named_container(name)?;
371        self.output_variant_index(variant_index)?;
372        Ok(self)
373    }
374
375    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
376        Ok(MapSerializer::new(self))
377    }
378
379    fn serialize_struct(
380        mut self,
381        name: &'static str,
382        _len: usize,
383    ) -> Result<Self::SerializeStruct> {
384        self.enter_named_container(name)?;
385        Ok(self)
386    }
387
388    fn serialize_struct_variant(
389        mut self,
390        name: &'static str,
391        variant_index: u32,
392        _variant: &'static str,
393        _len: usize,
394    ) -> Result<Self::SerializeStructVariant> {
395        self.enter_named_container(name)?;
396        self.output_variant_index(variant_index)?;
397        Ok(self)
398    }
399
400    // BCS is not a human readable format
401    fn is_human_readable(&self) -> bool {
402        false
403    }
404}
405
406impl<'a, W> ser::SerializeSeq for Serializer<'a, W>
407where
408    W: ?Sized + std::io::Write,
409{
410    type Ok = ();
411    type Error = Error;
412
413    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
414    where
415        T: ?Sized + Serialize,
416    {
417        value.serialize(Serializer::new(self.output, self.max_remaining_depth))
418    }
419
420    fn end(self) -> Result<()> {
421        Ok(())
422    }
423}
424
425impl<'a, W> ser::SerializeTuple for Serializer<'a, W>
426where
427    W: ?Sized + std::io::Write,
428{
429    type Ok = ();
430    type Error = Error;
431
432    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
433    where
434        T: ?Sized + Serialize,
435    {
436        value.serialize(Serializer::new(self.output, self.max_remaining_depth))
437    }
438
439    fn end(self) -> Result<()> {
440        Ok(())
441    }
442}
443
444impl<'a, W> ser::SerializeTupleStruct for Serializer<'a, W>
445where
446    W: ?Sized + std::io::Write,
447{
448    type Ok = ();
449    type Error = Error;
450
451    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
452    where
453        T: ?Sized + Serialize,
454    {
455        value.serialize(Serializer::new(self.output, self.max_remaining_depth))
456    }
457
458    fn end(self) -> Result<()> {
459        Ok(())
460    }
461}
462
463impl<'a, W> ser::SerializeTupleVariant for Serializer<'a, W>
464where
465    W: ?Sized + std::io::Write,
466{
467    type Ok = ();
468    type Error = Error;
469
470    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
471    where
472        T: ?Sized + Serialize,
473    {
474        value.serialize(Serializer::new(self.output, self.max_remaining_depth))
475    }
476
477    fn end(self) -> Result<()> {
478        Ok(())
479    }
480}
481
482#[doc(hidden)]
483struct MapSerializer<'a, W: ?Sized> {
484    serializer: Serializer<'a, W>,
485    entries: Vec<(Vec<u8>, Vec<u8>)>,
486    next_key: Option<Vec<u8>>,
487}
488
489impl<'a, W: ?Sized> MapSerializer<'a, W> {
490    fn new(serializer: Serializer<'a, W>) -> Self {
491        MapSerializer {
492            serializer,
493            entries: Vec::new(),
494            next_key: None,
495        }
496    }
497}
498
499impl<'a, W> ser::SerializeMap for MapSerializer<'a, W>
500where
501    W: ?Sized + std::io::Write,
502{
503    type Ok = ();
504    type Error = Error;
505
506    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
507    where
508        T: ?Sized + Serialize,
509    {
510        if self.next_key.is_some() {
511            return Err(Error::ExpectedMapValue);
512        }
513
514        let mut output = Vec::new();
515        key.serialize(Serializer::new(
516            &mut output,
517            self.serializer.max_remaining_depth,
518        ))?;
519        self.next_key = Some(output);
520        Ok(())
521    }
522
523    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
524    where
525        T: ?Sized + Serialize,
526    {
527        match self.next_key.take() {
528            Some(key) => {
529                let mut output = Vec::new();
530                value.serialize(Serializer::new(
531                    &mut output,
532                    self.serializer.max_remaining_depth,
533                ))?;
534                self.entries.push((key, output));
535                Ok(())
536            }
537            None => Err(Error::ExpectedMapKey),
538        }
539    }
540
541    fn end(mut self) -> Result<()> {
542        if self.next_key.is_some() {
543            return Err(Error::ExpectedMapValue);
544        }
545        self.entries.sort_by(|e1, e2| e1.0.cmp(&e2.0));
546        self.entries.dedup_by(|e1, e2| e1.0.eq(&e2.0));
547
548        let len = self.entries.len();
549        self.serializer.output_seq_len(len)?;
550
551        for (key, value) in &self.entries {
552            self.serializer.output.write_all(key)?;
553            self.serializer.output.write_all(value)?;
554        }
555
556        Ok(())
557    }
558}
559
560impl<'a, W> ser::SerializeStruct for Serializer<'a, W>
561where
562    W: ?Sized + std::io::Write,
563{
564    type Ok = ();
565    type Error = Error;
566
567    fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
568    where
569        T: ?Sized + Serialize,
570    {
571        value.serialize(Serializer::new(self.output, self.max_remaining_depth))
572    }
573
574    fn end(self) -> Result<()> {
575        Ok(())
576    }
577}
578
579impl<'a, W> ser::SerializeStructVariant for Serializer<'a, W>
580where
581    W: ?Sized + std::io::Write,
582{
583    type Ok = ();
584    type Error = Error;
585
586    fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
587    where
588        T: ?Sized + Serialize,
589    {
590        value.serialize(Serializer::new(self.output, self.max_remaining_depth))
591    }
592
593    fn end(self) -> Result<()> {
594        Ok(())
595    }
596}