1 //! Serialize a Rust data structure to CBOR data.
2 
3 #[cfg(feature = "alloc")]
4 use alloc::vec::Vec;
5 
6 #[cfg(feature = "std")]
7 pub use crate::write::IoWrite;
8 pub use crate::write::{SliceWrite, Write};
9 
10 use crate::error::{Error, Result};
11 use half::f16;
12 use serde::ser::{self, Serialize};
13 #[cfg(feature = "std")]
14 use std::io;
15 
16 use crate::tags::{get_tag, CBOR_NEWTYPE_NAME};
17 
18 /// Serializes a value to a vector.
19 #[cfg(any(feature = "std", feature = "alloc"))]
20 pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
21 where
22     T: ser::Serialize,
23 {
24     let mut vec = Vec::new();
25     value.serialize(&mut Serializer::new(&mut vec))?;
26     Ok(vec)
27 }
28 
29 /// Serializes a value to a vector in packed format.
30 #[cfg(feature = "std")]
31 pub fn to_vec_packed<T>(value: &T) -> Result<Vec<u8>>
32 where
33     T: ser::Serialize,
34 {
35     let mut vec = Vec::new();
36     value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).packed_format())?;
37     Ok(vec)
38 }
39 
40 /// Serializes a value to a writer.
41 #[cfg(feature = "std")]
42 pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
43 where
44     W: io::Write,
45     T: ser::Serialize,
46 {
47     value.serialize(&mut Serializer::new(&mut IoWrite::new(writer)))
48 }
49 
50 /// A structure for serializing Rust values to CBOR.
51 #[derive(Debug)]
52 pub struct Serializer<W> {
53     writer: W,
54     packed: bool,
55     enum_as_map: bool,
56 }
57 
58 impl<W> Serializer<W>
59 where
60     W: Write,
61 {
62     /// Creates a new CBOR serializer.
63     ///
64     /// `to_vec` and `to_writer` should normally be used instead of this method.
65     #[inline]
66     pub fn new(writer: W) -> Self {
67         Serializer {
68             writer,
69             packed: false,
70             enum_as_map: true,
71         }
72     }
73 
74     /// Choose concise/packed format for serializer.
75     ///
76     /// In the packed format enum variant names and field names
77     /// are replaced with numeric indizes to conserve space.
78     pub fn packed_format(mut self) -> Self {
79         self.packed = true;
80         self
81     }
82 
83     /// Enable old enum format used by `serde_cbor` versions <= v0.9.
84     ///
85     /// The `legacy_enums` option determines how enums are encoded.
86     ///
87     /// This makes no difference when encoding and decoding enums using
88     /// this crate, but it shows up when decoding to a `Value` or decoding
89     /// in other languages.
90     ///
91     /// # Examples
92     ///
93     /// Given the following enum
94     ///
95     /// ```rust
96     /// enum Enum {
97     ///     Unit,
98     ///     NewType(i32),
99     ///     Tuple(String, bool),
100     ///     Struct{ x: i32, y: i32 },
101     /// }
102     /// ```
103     /// we will give the `Value` with the same encoding for each case using
104     /// JSON notation.
105     ///
106     /// ## Default encodings
107     ///
108     /// * `Enum::Unit` encodes as `"Unit"`
109     /// * `Enum::NewType(10)` encodes as `{"NewType": 10}`
110     /// * `Enum::Tuple("x", true)` encodes as `{"Tuple": ["x", true]}`
111     ///
112     /// ## Legacy encodings
113     ///
114     /// * `Enum::Unit` encodes as `"Unit"`
115     /// * `Enum::NewType(10)` encodes as `["NewType", 10]`
116     /// * `Enum::Tuple("x", true)` encodes as `["Tuple", "x", true]`
117     /// * `Enum::Struct{ x: 5, y: -5 }` encodes as `["Struct", {"x": 5, "y": -5}]`
118     pub fn legacy_enums(mut self) -> Self {
119         self.enum_as_map = false;
120         self
121     }
122 
123     /// Writes a CBOR self-describe tag to the stream.
124     ///
125     /// Tagging allows a decoder to distinguish different file formats based on their content
126     /// without further information.
127     #[inline]
128     pub fn self_describe(&mut self) -> Result<()> {
129         let mut buf = [6 << 5 | 25, 0, 0];
130         (&mut buf[1..]).copy_from_slice(&55799u16.to_be_bytes());
131         self.writer.write_all(&buf).map_err(|e| e.into())
132     }
133 
134     /// Unwrap the `Writer` from the `Serializer`.
135     #[inline]
136     pub fn into_inner(self) -> W {
137         self.writer
138     }
139 
140     #[inline]
141     fn write_u8(&mut self, major: u8, value: u8) -> Result<()> {
142         if value <= 0x17 {
143             self.writer.write_all(&[major << 5 | value])
144         } else {
145             let buf = [major << 5 | 24, value];
146             self.writer.write_all(&buf)
147         }
148         .map_err(|e| e.into())
149     }
150 
151     #[inline]
152     fn write_u16(&mut self, major: u8, value: u16) -> Result<()> {
153         if value <= u16::from(u8::max_value()) {
154             self.write_u8(major, value as u8)
155         } else {
156             let mut buf = [major << 5 | 25, 0, 0];
157             (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
158             self.writer.write_all(&buf).map_err(|e| e.into())
159         }
160     }
161 
162     #[inline]
163     fn write_u32(&mut self, major: u8, value: u32) -> Result<()> {
164         if value <= u32::from(u16::max_value()) {
165             self.write_u16(major, value as u16)
166         } else {
167             let mut buf = [major << 5 | 26, 0, 0, 0, 0];
168             (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
169             self.writer.write_all(&buf).map_err(|e| e.into())
170         }
171     }
172 
173     #[inline]
174     fn write_u64(&mut self, major: u8, value: u64) -> Result<()> {
175         if value <= u64::from(u32::max_value()) {
176             self.write_u32(major, value as u32)
177         } else {
178             let mut buf = [major << 5 | 27, 0, 0, 0, 0, 0, 0, 0, 0];
179             (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
180             self.writer.write_all(&buf).map_err(|e| e.into())
181         }
182     }
183 
184     #[inline]
185     fn serialize_collection<'a>(
186         &'a mut self,
187         major: u8,
188         len: Option<usize>,
189     ) -> Result<CollectionSerializer<'a, W>> {
190         let needs_eof = match len {
191             Some(len) => {
192                 self.write_u64(major, len as u64)?;
193                 false
194             }
195             None => {
196                 self.writer
197                     .write_all(&[major << 5 | 31])
198                     .map_err(|e| e.into())?;
199                 true
200             }
201         };
202 
203         Ok(CollectionSerializer {
204             ser: self,
205             needs_eof,
206         })
207     }
208 }
209 
210 impl<'a, W> ser::Serializer for &'a mut Serializer<W>
211 where
212     W: Write,
213 {
214     type Ok = ();
215     type Error = Error;
216 
217     type SerializeSeq = CollectionSerializer<'a, W>;
218     type SerializeTuple = &'a mut Serializer<W>;
219     type SerializeTupleStruct = &'a mut Serializer<W>;
220     type SerializeTupleVariant = &'a mut Serializer<W>;
221     type SerializeMap = CollectionSerializer<'a, W>;
222     type SerializeStruct = StructSerializer<'a, W>;
223     type SerializeStructVariant = StructSerializer<'a, W>;
224 
225     #[inline]
226     fn serialize_bool(self, value: bool) -> Result<()> {
227         let value = if value { 0xf5 } else { 0xf4 };
228         self.writer.write_all(&[value]).map_err(|e| e.into())
229     }
230 
231     #[inline]
232     fn serialize_i8(self, value: i8) -> Result<()> {
233         if value < 0 {
234             self.write_u8(1, -(value + 1) as u8)
235         } else {
236             self.write_u8(0, value as u8)
237         }
238     }
239 
240     #[inline]
241     fn serialize_i16(self, value: i16) -> Result<()> {
242         if value < 0 {
243             self.write_u16(1, -(value + 1) as u16)
244         } else {
245             self.write_u16(0, value as u16)
246         }
247     }
248 
249     #[inline]
250     fn serialize_i32(self, value: i32) -> Result<()> {
251         if value < 0 {
252             self.write_u32(1, -(value + 1) as u32)
253         } else {
254             self.write_u32(0, value as u32)
255         }
256     }
257 
258     #[inline]
259     fn serialize_i64(self, value: i64) -> Result<()> {
260         if value < 0 {
261             self.write_u64(1, -(value + 1) as u64)
262         } else {
263             self.write_u64(0, value as u64)
264         }
265     }
266 
267     #[inline]
268     fn serialize_i128(self, value: i128) -> Result<()> {
269         if value < 0 {
270             if -(value + 1) > i128::from(u64::max_value()) {
271                 return Err(Error::message("The number can't be stored in CBOR"));
272             }
273             self.write_u64(1, -(value + 1) as u64)
274         } else {
275             if value > i128::from(u64::max_value()) {
276                 return Err(Error::message("The number can't be stored in CBOR"));
277             }
278             self.write_u64(0, value as u64)
279         }
280     }
281 
282     #[inline]
283     fn serialize_u8(self, value: u8) -> Result<()> {
284         self.write_u8(0, value)
285     }
286 
287     #[inline]
288     fn serialize_u16(self, value: u16) -> Result<()> {
289         self.write_u16(0, value)
290     }
291 
292     #[inline]
293     fn serialize_u32(self, value: u32) -> Result<()> {
294         self.write_u32(0, value)
295     }
296 
297     #[inline]
298     fn serialize_u64(self, value: u64) -> Result<()> {
299         self.write_u64(0, value)
300     }
301 
302     #[inline]
303     fn serialize_u128(self, value: u128) -> Result<()> {
304         if value > u128::from(u64::max_value()) {
305             return Err(Error::message("The number can't be stored in CBOR"));
306         }
307         self.write_u64(0, value as u64)
308     }
309 
310     #[inline]
311     #[allow(clippy::float_cmp)]
312     fn serialize_f32(self, value: f32) -> Result<()> {
313         if value.is_infinite() {
314             if value.is_sign_positive() {
315                 self.writer.write_all(&[0xf9, 0x7c, 0x00])
316             } else {
317                 self.writer.write_all(&[0xf9, 0xfc, 0x00])
318             }
319         } else if value.is_nan() {
320             self.writer.write_all(&[0xf9, 0x7e, 0x00])
321         } else if f32::from(f16::from_f32(value)) == value {
322             let mut buf = [0xf9, 0, 0];
323             (&mut buf[1..]).copy_from_slice(&f16::from_f32(value).to_bits().to_be_bytes());
324             self.writer.write_all(&buf)
325         } else {
326             let mut buf = [0xfa, 0, 0, 0, 0];
327             (&mut buf[1..]).copy_from_slice(&value.to_bits().to_be_bytes());
328             self.writer.write_all(&buf)
329         }
330         .map_err(|e| e.into())
331     }
332 
333     #[inline]
334     #[allow(clippy::float_cmp)]
335     fn serialize_f64(self, value: f64) -> Result<()> {
336         if !value.is_finite() || f64::from(value as f32) == value {
337             self.serialize_f32(value as f32)
338         } else {
339             let mut buf = [0xfb, 0, 0, 0, 0, 0, 0, 0, 0];
340             (&mut buf[1..]).copy_from_slice(&value.to_bits().to_be_bytes());
341             self.writer.write_all(&buf).map_err(|e| e.into())
342         }
343     }
344 
345     #[inline]
346     fn serialize_char(self, value: char) -> Result<()> {
347         // A char encoded as UTF-8 takes 4 bytes at most.
348         let mut buf = [0; 4];
349         self.serialize_str(value.encode_utf8(&mut buf))
350     }
351 
352     #[inline]
353     fn serialize_str(self, value: &str) -> Result<()> {
354         self.write_u64(3, value.len() as u64)?;
355         self.writer
356             .write_all(value.as_bytes())
357             .map_err(|e| e.into())
358     }
359 
360     #[inline]
361     fn serialize_bytes(self, value: &[u8]) -> Result<()> {
362         self.write_u64(2, value.len() as u64)?;
363         self.writer.write_all(value).map_err(|e| e.into())
364     }
365 
366     #[inline]
367     fn serialize_unit(self) -> Result<()> {
368         self.serialize_none()
369     }
370 
371     #[inline]
372     fn serialize_some<T>(self, value: &T) -> Result<()>
373     where
374         T: ?Sized + ser::Serialize,
375     {
376         value.serialize(self)
377     }
378 
379     #[inline]
380     fn serialize_none(self) -> Result<()> {
381         self.writer.write_all(&[0xf6]).map_err(|e| e.into())
382     }
383 
384     #[inline]
385     fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
386         self.serialize_unit()
387     }
388 
389     #[inline]
390     fn serialize_unit_variant(
391         self,
392         _name: &'static str,
393         variant_index: u32,
394         variant: &'static str,
395     ) -> Result<()> {
396         if self.packed {
397             self.serialize_u32(variant_index)
398         } else {
399             self.serialize_str(variant)
400         }
401     }
402 
403     #[inline]
404     fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
405     where
406         T: ?Sized + ser::Serialize,
407     {
408         if name == CBOR_NEWTYPE_NAME {
409             for tag in get_tag().into_iter() {
410                 self.write_u64(6, tag)?;
411             }
412         }
413         value.serialize(self)
414     }
415 
416     #[inline]
417     fn serialize_newtype_variant<T>(
418         self,
419         name: &'static str,
420         variant_index: u32,
421         variant: &'static str,
422         value: &T,
423     ) -> Result<()>
424     where
425         T: ?Sized + ser::Serialize,
426     {
427         if self.enum_as_map {
428             self.write_u64(5, 1u64)?;
429             variant.serialize(&mut *self)?;
430         } else {
431             self.writer.write_all(&[4 << 5 | 2]).map_err(|e| e.into())?;
432             self.serialize_unit_variant(name, variant_index, variant)?;
433         }
434         value.serialize(self)
435     }
436 
437     #[inline]
438     fn serialize_seq(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
439         self.serialize_collection(4, len)
440     }
441 
442     #[inline]
443     fn serialize_tuple(self, len: usize) -> Result<&'a mut Serializer<W>> {
444         self.write_u64(4, len as u64)?;
445         Ok(self)
446     }
447 
448     #[inline]
449     fn serialize_tuple_struct(
450         self,
451         _name: &'static str,
452         len: usize,
453     ) -> Result<&'a mut Serializer<W>> {
454         self.serialize_tuple(len)
455     }
456 
457     #[inline]
458     fn serialize_tuple_variant(
459         self,
460         name: &'static str,
461         variant_index: u32,
462         variant: &'static str,
463         len: usize,
464     ) -> Result<&'a mut Serializer<W>> {
465         if self.enum_as_map {
466             self.write_u64(5, 1u64)?;
467             variant.serialize(&mut *self)?;
468             self.serialize_tuple(len)
469         } else {
470             self.write_u64(4, (len + 1) as u64)?;
471             self.serialize_unit_variant(name, variant_index, variant)?;
472             Ok(self)
473         }
474     }
475 
476     #[inline]
477     fn serialize_map(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
478         self.serialize_collection(5, len)
479     }
480 
481     #[cfg(not(feature = "std"))]
482     fn collect_str<T: ?Sized>(self, value: &T) -> Result<()>
483     where
484         T: core::fmt::Display,
485     {
486         use crate::write::FmtWrite;
487         use core::fmt::Write;
488 
489         let mut w = FmtWrite::new(&mut self.writer);
490         write!(w, "{}", value)?;
491         Ok(())
492     }
493 
494     #[inline]
495     fn serialize_struct(self, _name: &'static str, len: usize) -> Result<StructSerializer<'a, W>> {
496         self.write_u64(5, len as u64)?;
497         Ok(StructSerializer { ser: self, idx: 0 })
498     }
499 
500     #[inline]
501     fn serialize_struct_variant(
502         self,
503         name: &'static str,
504         variant_index: u32,
505         variant: &'static str,
506         len: usize,
507     ) -> Result<StructSerializer<'a, W>> {
508         if self.enum_as_map {
509             self.write_u64(5, 1u64)?;
510         } else {
511             self.writer.write_all(&[4 << 5 | 2]).map_err(|e| e.into())?;
512         }
513         self.serialize_unit_variant(name, variant_index, variant)?;
514         self.serialize_struct(name, len)
515     }
516 
517     #[inline]
518     fn is_human_readable(&self) -> bool {
519         false
520     }
521 }
522 
523 impl<'a, W> ser::SerializeTuple for &'a mut Serializer<W>
524 where
525     W: Write,
526 {
527     type Ok = ();
528     type Error = Error;
529 
530     #[inline]
531     fn serialize_element<T>(&mut self, value: &T) -> Result<()>
532     where
533         T: ?Sized + ser::Serialize,
534     {
535         value.serialize(&mut **self)
536     }
537 
538     #[inline]
539     fn end(self) -> Result<()> {
540         Ok(())
541     }
542 }
543 
544 impl<'a, W> ser::SerializeTupleStruct for &'a mut Serializer<W>
545 where
546     W: Write,
547 {
548     type Ok = ();
549     type Error = Error;
550 
551     #[inline]
552     fn serialize_field<T>(&mut self, value: &T) -> Result<()>
553     where
554         T: ?Sized + ser::Serialize,
555     {
556         value.serialize(&mut **self)
557     }
558 
559     #[inline]
560     fn end(self) -> Result<()> {
561         Ok(())
562     }
563 }
564 
565 impl<'a, W> ser::SerializeTupleVariant for &'a mut Serializer<W>
566 where
567     W: Write,
568 {
569     type Ok = ();
570     type Error = Error;
571 
572     #[inline]
573     fn serialize_field<T>(&mut self, value: &T) -> Result<()>
574     where
575         T: ?Sized + ser::Serialize,
576     {
577         value.serialize(&mut **self)
578     }
579 
580     #[inline]
581     fn end(self) -> Result<()> {
582         Ok(())
583     }
584 }
585 
586 #[doc(hidden)]
587 pub struct StructSerializer<'a, W> {
588     ser: &'a mut Serializer<W>,
589     idx: u32,
590 }
591 
592 impl<'a, W> StructSerializer<'a, W>
593 where
594     W: Write,
595 {
596     #[inline]
597     fn serialize_field_inner<T>(&mut self, key: &'static str, value: &T) -> Result<()>
598     where
599         T: ?Sized + ser::Serialize,
600     {
601         if self.ser.packed {
602             self.idx.serialize(&mut *self.ser)?;
603         } else {
604             key.serialize(&mut *self.ser)?;
605         }
606         value.serialize(&mut *self.ser)?;
607         self.idx += 1;
608         Ok(())
609     }
610 
611     #[inline]
612     fn skip_field_inner(&mut self, _: &'static str) -> Result<()> {
613         self.idx += 1;
614         Ok(())
615     }
616 
617     #[inline]
618     fn end_inner(self) -> Result<()> {
619         Ok(())
620     }
621 }
622 
623 impl<'a, W> ser::SerializeStruct for StructSerializer<'a, W>
624 where
625     W: Write,
626 {
627     type Ok = ();
628     type Error = Error;
629 
630     #[inline]
631     fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
632     where
633         T: ?Sized + ser::Serialize,
634     {
635         self.serialize_field_inner(key, value)
636     }
637 
638     #[inline]
639     fn skip_field(&mut self, key: &'static str) -> Result<()> {
640         self.skip_field_inner(key)
641     }
642 
643     #[inline]
644     fn end(self) -> Result<()> {
645         self.end_inner()
646     }
647 }
648 
649 impl<'a, W> ser::SerializeStructVariant for StructSerializer<'a, W>
650 where
651     W: Write,
652 {
653     type Ok = ();
654     type Error = Error;
655 
656     #[inline]
657     fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
658     where
659         T: ?Sized + ser::Serialize,
660     {
661         self.serialize_field_inner(key, value)
662     }
663 
664     #[inline]
665     fn skip_field(&mut self, key: &'static str) -> Result<()> {
666         self.skip_field_inner(key)
667     }
668 
669     #[inline]
670     fn end(self) -> Result<()> {
671         self.end_inner()
672     }
673 }
674 
675 #[doc(hidden)]
676 pub struct CollectionSerializer<'a, W> {
677     ser: &'a mut Serializer<W>,
678     needs_eof: bool,
679 }
680 
681 impl<'a, W> CollectionSerializer<'a, W>
682 where
683     W: Write,
684 {
685     #[inline]
686     fn end_inner(self) -> Result<()> {
687         if self.needs_eof {
688             self.ser.writer.write_all(&[0xff]).map_err(|e| e.into())
689         } else {
690             Ok(())
691         }
692     }
693 }
694 
695 impl<'a, W> ser::SerializeSeq for CollectionSerializer<'a, W>
696 where
697     W: Write,
698 {
699     type Ok = ();
700     type Error = Error;
701 
702     #[inline]
703     fn serialize_element<T>(&mut self, value: &T) -> Result<()>
704     where
705         T: ?Sized + ser::Serialize,
706     {
707         value.serialize(&mut *self.ser)
708     }
709 
710     #[inline]
711     fn end(self) -> Result<()> {
712         self.end_inner()
713     }
714 }
715 
716 impl<'a, W> ser::SerializeMap for CollectionSerializer<'a, W>
717 where
718     W: Write,
719 {
720     type Ok = ();
721     type Error = Error;
722 
723     #[inline]
724     fn serialize_key<T>(&mut self, key: &T) -> Result<()>
725     where
726         T: ?Sized + ser::Serialize,
727     {
728         key.serialize(&mut *self.ser)
729     }
730 
731     #[inline]
732     fn serialize_value<T>(&mut self, value: &T) -> Result<()>
733     where
734         T: ?Sized + ser::Serialize,
735     {
736         value.serialize(&mut *self.ser)
737     }
738 
739     #[inline]
740     fn end(self) -> Result<()> {
741         self.end_inner()
742     }
743 }
744