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