ciborium/ser/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Serde serialization support for CBOR
4
5mod error;
6
7pub use error::Error;
8
9use alloc::string::ToString;
10
11use ciborium_io::Write;
12use ciborium_ll::*;
13use serde::{ser, Serialize as _};
14
15struct Serializer<W: Write>(Encoder<W>);
16
17impl<W: Write> From<W> for Serializer<W> {
18    #[inline]
19    fn from(writer: W) -> Self {
20        Self(writer.into())
21    }
22}
23
24impl<W: Write> From<Encoder<W>> for Serializer<W> {
25    #[inline]
26    fn from(writer: Encoder<W>) -> Self {
27        Self(writer)
28    }
29}
30
31impl<'a, W: Write> ser::Serializer for &'a mut Serializer<W>
32where
33    W::Error: core::fmt::Debug,
34{
35    type Ok = ();
36    type Error = Error<W::Error>;
37
38    type SerializeSeq = CollectionSerializer<'a, W>;
39    type SerializeTuple = CollectionSerializer<'a, W>;
40    type SerializeTupleStruct = CollectionSerializer<'a, W>;
41    type SerializeTupleVariant = CollectionSerializer<'a, W>;
42    type SerializeMap = CollectionSerializer<'a, W>;
43    type SerializeStruct = CollectionSerializer<'a, W>;
44    type SerializeStructVariant = CollectionSerializer<'a, W>;
45
46    #[inline]
47    fn serialize_bool(self, v: bool) -> Result<(), Self::Error> {
48        Ok(self.0.push(match v {
49            false => Header::Simple(simple::FALSE),
50            true => Header::Simple(simple::TRUE),
51        })?)
52    }
53
54    #[inline]
55    fn serialize_i8(self, v: i8) -> Result<(), Self::Error> {
56        self.serialize_i64(v.into())
57    }
58
59    #[inline]
60    fn serialize_i16(self, v: i16) -> Result<(), Self::Error> {
61        self.serialize_i64(v.into())
62    }
63
64    #[inline]
65    fn serialize_i32(self, v: i32) -> Result<(), Self::Error> {
66        self.serialize_i64(v.into())
67    }
68
69    #[inline]
70    fn serialize_i64(self, v: i64) -> Result<(), Self::Error> {
71        Ok(self.0.push(match v.is_negative() {
72            false => Header::Positive(v as u64),
73            true => Header::Negative(v as u64 ^ !0),
74        })?)
75    }
76
77    #[inline]
78    fn serialize_i128(self, v: i128) -> Result<(), Self::Error> {
79        let (tag, raw) = match v.is_negative() {
80            false => (tag::BIGPOS, v as u128),
81            true => (tag::BIGNEG, v as u128 ^ !0),
82        };
83
84        match (tag, u64::try_from(raw)) {
85            (tag::BIGPOS, Ok(x)) => return Ok(self.0.push(Header::Positive(x))?),
86            (tag::BIGNEG, Ok(x)) => return Ok(self.0.push(Header::Negative(x))?),
87            _ => {}
88        }
89
90        let bytes = raw.to_be_bytes();
91
92        // Skip leading zeros.
93        let mut slice = &bytes[..];
94        while !slice.is_empty() && slice[0] == 0 {
95            slice = &slice[1..];
96        }
97
98        self.0.push(Header::Tag(tag))?;
99        self.0.push(Header::Bytes(Some(slice.len())))?;
100        Ok(self.0.write_all(slice)?)
101    }
102
103    #[inline]
104    fn serialize_u8(self, v: u8) -> Result<(), Self::Error> {
105        self.serialize_u64(v.into())
106    }
107
108    #[inline]
109    fn serialize_u16(self, v: u16) -> Result<(), Self::Error> {
110        self.serialize_u64(v.into())
111    }
112
113    #[inline]
114    fn serialize_u32(self, v: u32) -> Result<(), Self::Error> {
115        self.serialize_u64(v.into())
116    }
117
118    #[inline]
119    fn serialize_u64(self, v: u64) -> Result<(), Self::Error> {
120        Ok(self.0.push(Header::Positive(v))?)
121    }
122
123    #[inline]
124    fn serialize_u128(self, v: u128) -> Result<(), Self::Error> {
125        if let Ok(x) = u64::try_from(v) {
126            return self.serialize_u64(x);
127        }
128
129        let bytes = v.to_be_bytes();
130
131        // Skip leading zeros.
132        let mut slice = &bytes[..];
133        while !slice.is_empty() && slice[0] == 0 {
134            slice = &slice[1..];
135        }
136
137        self.0.push(Header::Tag(tag::BIGPOS))?;
138        self.0.push(Header::Bytes(Some(slice.len())))?;
139        Ok(self.0.write_all(slice)?)
140    }
141
142    #[inline]
143    fn serialize_f32(self, v: f32) -> Result<(), Self::Error> {
144        self.serialize_f64(v.into())
145    }
146
147    #[inline]
148    fn serialize_f64(self, v: f64) -> Result<(), Self::Error> {
149        Ok(self.0.push(Header::Float(v))?)
150    }
151
152    #[inline]
153    fn serialize_char(self, v: char) -> Result<(), Self::Error> {
154        self.serialize_str(&v.to_string())
155    }
156
157    #[inline]
158    fn serialize_str(self, v: &str) -> Result<(), Self::Error> {
159        let bytes = v.as_bytes();
160        self.0.push(Header::Text(bytes.len().into()))?;
161        Ok(self.0.write_all(bytes)?)
162    }
163
164    #[inline]
165    fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
166        self.0.push(Header::Bytes(v.len().into()))?;
167        Ok(self.0.write_all(v)?)
168    }
169
170    #[inline]
171    fn serialize_none(self) -> Result<(), Self::Error> {
172        Ok(self.0.push(Header::Simple(simple::NULL))?)
173    }
174
175    #[inline]
176    fn serialize_some<U: ?Sized + ser::Serialize>(self, value: &U) -> Result<(), Self::Error> {
177        value.serialize(self)
178    }
179
180    #[inline]
181    fn serialize_unit(self) -> Result<(), Self::Error> {
182        self.serialize_none()
183    }
184
185    #[inline]
186    fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error> {
187        self.serialize_unit()
188    }
189
190    #[inline]
191    fn serialize_unit_variant(
192        self,
193        _name: &'static str,
194        _index: u32,
195        variant: &'static str,
196    ) -> Result<(), Self::Error> {
197        self.serialize_str(variant)
198    }
199
200    #[inline]
201    fn serialize_newtype_struct<U: ?Sized + ser::Serialize>(
202        self,
203        _name: &'static str,
204        value: &U,
205    ) -> Result<(), Self::Error> {
206        value.serialize(self)
207    }
208
209    #[inline]
210    fn serialize_newtype_variant<U: ?Sized + ser::Serialize>(
211        self,
212        name: &'static str,
213        _index: u32,
214        variant: &'static str,
215        value: &U,
216    ) -> Result<(), Self::Error> {
217        if name != "@@TAG@@" || variant != "@@UNTAGGED@@" {
218            self.0.push(Header::Map(Some(1)))?;
219            self.serialize_str(variant)?;
220        }
221
222        value.serialize(self)
223    }
224
225    #[inline]
226    fn serialize_seq(self, length: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
227        self.0.push(Header::Array(length))?;
228        Ok(CollectionSerializer {
229            encoder: self,
230            ending: length.is_none(),
231            tag: false,
232        })
233    }
234
235    #[inline]
236    fn serialize_tuple(self, length: usize) -> Result<Self::SerializeTuple, Self::Error> {
237        self.serialize_seq(Some(length))
238    }
239
240    #[inline]
241    fn serialize_tuple_struct(
242        self,
243        _name: &'static str,
244        length: usize,
245    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
246        self.serialize_seq(Some(length))
247    }
248
249    #[inline]
250    fn serialize_tuple_variant(
251        self,
252        name: &'static str,
253        _index: u32,
254        variant: &'static str,
255        length: usize,
256    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
257        match (name, variant) {
258            ("@@TAG@@", "@@TAGGED@@") => Ok(CollectionSerializer {
259                encoder: self,
260                ending: false,
261                tag: true,
262            }),
263
264            _ => {
265                self.0.push(Header::Map(Some(1)))?;
266                self.serialize_str(variant)?;
267                self.0.push(Header::Array(Some(length)))?;
268                Ok(CollectionSerializer {
269                    encoder: self,
270                    ending: false,
271                    tag: false,
272                })
273            }
274        }
275    }
276
277    #[inline]
278    fn serialize_map(self, length: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
279        self.0.push(Header::Map(length))?;
280        Ok(CollectionSerializer {
281            encoder: self,
282            ending: length.is_none(),
283            tag: false,
284        })
285    }
286
287    #[inline]
288    fn serialize_struct(
289        self,
290        _name: &'static str,
291        length: usize,
292    ) -> Result<Self::SerializeStruct, Self::Error> {
293        self.0.push(Header::Map(Some(length)))?;
294        Ok(CollectionSerializer {
295            encoder: self,
296            ending: false,
297            tag: false,
298        })
299    }
300
301    #[inline]
302    fn serialize_struct_variant(
303        self,
304        _name: &'static str,
305        _index: u32,
306        variant: &'static str,
307        length: usize,
308    ) -> Result<Self::SerializeStructVariant, Self::Error> {
309        self.0.push(Header::Map(Some(1)))?;
310        self.serialize_str(variant)?;
311        self.0.push(Header::Map(Some(length)))?;
312        Ok(CollectionSerializer {
313            encoder: self,
314            ending: false,
315            tag: false,
316        })
317    }
318
319    #[inline]
320    fn is_human_readable(&self) -> bool {
321        false
322    }
323}
324
325macro_rules! end {
326    () => {
327        #[inline]
328        fn end(self) -> Result<(), Self::Error> {
329            if self.ending {
330                self.encoder.0.push(Header::Break)?;
331            }
332
333            Ok(())
334        }
335    };
336}
337
338struct CollectionSerializer<'a, W: Write> {
339    encoder: &'a mut Serializer<W>,
340    ending: bool,
341    tag: bool,
342}
343
344impl<'a, W: Write> ser::SerializeSeq for CollectionSerializer<'a, W>
345where
346    W::Error: core::fmt::Debug,
347{
348    type Ok = ();
349    type Error = Error<W::Error>;
350
351    #[inline]
352    fn serialize_element<U: ?Sized + ser::Serialize>(
353        &mut self,
354        value: &U,
355    ) -> Result<(), Self::Error> {
356        value.serialize(&mut *self.encoder)
357    }
358
359    end!();
360}
361
362impl<'a, W: Write> ser::SerializeTuple for CollectionSerializer<'a, W>
363where
364    W::Error: core::fmt::Debug,
365{
366    type Ok = ();
367    type Error = Error<W::Error>;
368
369    #[inline]
370    fn serialize_element<U: ?Sized + ser::Serialize>(
371        &mut self,
372        value: &U,
373    ) -> Result<(), Self::Error> {
374        value.serialize(&mut *self.encoder)
375    }
376
377    end!();
378}
379
380impl<'a, W: Write> ser::SerializeTupleStruct for CollectionSerializer<'a, W>
381where
382    W::Error: core::fmt::Debug,
383{
384    type Ok = ();
385    type Error = Error<W::Error>;
386
387    #[inline]
388    fn serialize_field<U: ?Sized + ser::Serialize>(
389        &mut self,
390        value: &U,
391    ) -> Result<(), Self::Error> {
392        value.serialize(&mut *self.encoder)
393    }
394
395    end!();
396}
397
398impl<'a, W: Write> ser::SerializeTupleVariant for CollectionSerializer<'a, W>
399where
400    W::Error: core::fmt::Debug,
401{
402    type Ok = ();
403    type Error = Error<W::Error>;
404
405    #[inline]
406    fn serialize_field<U: ?Sized + ser::Serialize>(
407        &mut self,
408        value: &U,
409    ) -> Result<(), Self::Error> {
410        if !self.tag {
411            return value.serialize(&mut *self.encoder);
412        }
413
414        self.tag = false;
415        match value.serialize(crate::tag::Serializer) {
416            Ok(x) => Ok(self.encoder.0.push(Header::Tag(x))?),
417            _ => Err(Error::Value("expected tag".into())),
418        }
419    }
420
421    end!();
422}
423
424impl<'a, W: Write> ser::SerializeMap for CollectionSerializer<'a, W>
425where
426    W::Error: core::fmt::Debug,
427{
428    type Ok = ();
429    type Error = Error<W::Error>;
430
431    #[inline]
432    fn serialize_key<U: ?Sized + ser::Serialize>(&mut self, key: &U) -> Result<(), Self::Error> {
433        key.serialize(&mut *self.encoder)
434    }
435
436    #[inline]
437    fn serialize_value<U: ?Sized + ser::Serialize>(
438        &mut self,
439        value: &U,
440    ) -> Result<(), Self::Error> {
441        value.serialize(&mut *self.encoder)
442    }
443
444    end!();
445}
446
447impl<'a, W: Write> ser::SerializeStruct for CollectionSerializer<'a, W>
448where
449    W::Error: core::fmt::Debug,
450{
451    type Ok = ();
452    type Error = Error<W::Error>;
453
454    #[inline]
455    fn serialize_field<U: ?Sized + ser::Serialize>(
456        &mut self,
457        key: &'static str,
458        value: &U,
459    ) -> Result<(), Self::Error> {
460        key.serialize(&mut *self.encoder)?;
461        value.serialize(&mut *self.encoder)?;
462        Ok(())
463    }
464
465    end!();
466}
467
468impl<'a, W: Write> ser::SerializeStructVariant for CollectionSerializer<'a, W>
469where
470    W::Error: core::fmt::Debug,
471{
472    type Ok = ();
473    type Error = Error<W::Error>;
474
475    #[inline]
476    fn serialize_field<U: ?Sized + ser::Serialize>(
477        &mut self,
478        key: &'static str,
479        value: &U,
480    ) -> Result<(), Self::Error> {
481        key.serialize(&mut *self.encoder)?;
482        value.serialize(&mut *self.encoder)
483    }
484
485    end!();
486}
487
488/// Serializes as CBOR into a type with [`impl ciborium_io::Write`](ciborium_io::Write)
489#[inline]
490pub fn into_writer<T: ?Sized + ser::Serialize, W: Write>(
491    value: &T,
492    writer: W,
493) -> Result<(), Error<W::Error>>
494where
495    W::Error: core::fmt::Debug,
496{
497    let mut encoder = Serializer::from(writer);
498    value.serialize(&mut encoder)
499}