Skip to main content

deser_cbor/
ser.rs

1use alloc::boxed::Box;
2use alloc::string::ToString;
3use alloc::vec::Vec;
4use core::mem::ManuallyDrop;
5
6use deser_core::State;
7use deser_core::ext::{BigInt, Datetime, Decimal, ExtValue, RawInput, Timestamp, Uuid};
8use deser_core::ser::SerializeRef;
9use deser_core::ser::{self, EventSink, SerializeDriver};
10use deser_core::{Atom, ContainerShape, Error, ErrorKind, Event, Serialize};
11
12use crate::copy::extend;
13use crate::float::f32_to_f16;
14use crate::simple::Simple;
15use crate::tag::Tags;
16
17const MAJOR_UNSIGNED: u8 = 0;
18const MAJOR_NEGATIVE: u8 = 1;
19const MAJOR_BYTES: u8 = 2;
20const MAJOR_TEXT: u8 = 3;
21const MAJOR_ARRAY: u8 = 4;
22const MAJOR_MAP: u8 = 5;
23const MAJOR_TAG: u8 = 6;
24
25/// Configures how values are serialized to CBOR.
26///
27/// The output uses the preferred serialization of RFC 8949: integers,
28/// lengths and floats use their shortest (lossless) form and all maps and
29/// arrays have a definite length.
30///
31/// If [`set_canonical`](Self::set_canonical) is enabled, the output is
32/// additionally deterministically encoded (RFC 8949 §4.2.1): the entries of
33/// maps are sorted by the bytewise lexicographic order of their encoded keys
34/// and duplicate keys are rejected.
35///
36/// ```
37/// use std::collections::HashMap;
38/// use deser_cbor::SerializerConfig;
39///
40/// const CANONICAL: SerializerConfig =
41///     SerializerConfig::builder().canonical(true).build();
42/// let map = HashMap::from([("b", 1), ("a", 2)]);
43/// assert_eq!(CANONICAL.to_vec(&map).unwrap(), b"\xa2\x61a\x02\x61b\x01");
44/// ```
45#[derive(Debug, Clone, Default, PartialEq, Eq)]
46pub struct SerializerConfig {
47    canonical: bool,
48    context: deser_core::Context,
49}
50
51/// An open map or array (or the top level).
52///
53/// This is kept small as it's moved to the stack and back for every
54/// container.
55#[derive(Clone, Copy)]
56struct Frame {
57    /// Counts down with every item (for maps keys and values are counted
58    /// separately).  If the length is known, it starts at the number of
59    /// items the header announced and ends at zero.  Otherwise it starts
60    /// at `u64::MAX` and the length is patched into the header at the end.
61    remaining: u64,
62    /// The offset of the header shifted by two, the flags [`IS_MAP`] and
63    /// [`UNKNOWN_LEN`] are in the lower bits.
64    info: usize,
65}
66
67const IS_MAP: usize = 1;
68const UNKNOWN_LEN: usize = 2;
69
70impl Frame {
71    /// The frame of the top level, which is not a container.
72    const TOP: Frame = Frame {
73        remaining: u64::MAX,
74        info: UNKNOWN_LEN,
75    };
76
77    #[inline(always)]
78    fn is_map(self) -> bool {
79        self.info & IS_MAP != 0
80    }
81
82    #[inline(always)]
83    fn header(self) -> usize {
84        self.info >> 2
85    }
86}
87
88/// The start of a map in canonical mode.
89struct CanonicalMap {
90    /// The offset of the content (after the header).
91    body: usize,
92    /// The index into the entry offsets where the offsets of this map
93    /// begin.
94    offsets_start: usize,
95}
96
97/// Holds the state of the serializer while writing.
98pub(crate) struct Writer {
99    pub(crate) out: Vec<u8>,
100    canonical: bool,
101    // the frame of the current container is held here, the frames of the
102    // outer containers are saved on the stack.
103    frame: Frame,
104    stack: Vec<Frame>,
105    // in canonical mode the open maps and the offsets of their keys and
106    // values
107    maps: Vec<CanonicalMap>,
108    offsets: Vec<usize>,
109    // bytes to be inserted into the output at the end, see `patch_length`.
110    insertions: Vec<Insertion>,
111    // the number of open containers whose length is patched in at the end
112    open_unknown: usize,
113    // the output is passed on once it's this long (see `EventSink`)
114    limit: usize,
115}
116
117/// The bytes of a container header that did not fit into the space
118/// reserved for it.
119struct Insertion {
120    offset: usize,
121    len: u8,
122    bytes: [u8; 8],
123}
124
125impl EventSink for Writer {
126    #[inline(always)]
127    fn event(
128        &mut self,
129        event: Event<'_>,
130        _value: SerializeRef<'_>,
131        state: &mut State,
132    ) -> Result<(), Error> {
133        Writer::event(self, event, state)
134    }
135
136    #[inline]
137    fn pause(&mut self) -> bool {
138        // the output is final once no length has to be patched in and no
139        // map has to be sorted
140        if self.out.len() < self.limit || self.open_unknown > 0 || !self.maps.is_empty() {
141            return false;
142        }
143        self.finish();
144        true
145    }
146}
147
148impl Writer {
149    /// Creates a writer that writes into the output.
150    pub(crate) fn new(canonical: bool, out: Vec<u8>) -> Writer {
151        Writer {
152            out,
153            canonical,
154            frame: Frame::TOP,
155            stack: Vec::new(),
156            maps: Vec::new(),
157            offsets: Vec::new(),
158            insertions: Vec::new(),
159            open_unknown: 0,
160            limit: usize::MAX,
161        }
162    }
163
164    /// Makes the output final once no container is open whose length is
165    /// patched in or which is sorted.
166    pub(crate) fn finish(&mut self) {
167        if !self.insertions.is_empty() {
168            self.apply_insertions();
169            self.insertions.clear();
170        }
171    }
172
173    /// Declares that raw CBOR values are written as they are.
174    ///
175    /// Canonical output encodes them again, their encoding might not be
176    /// canonical.
177    fn accept_raw(&self, driver: &mut SerializeDriver<'_>) {
178        if !self.canonical {
179            driver.state_mut().declare_raw_format(&crate::raw::ID);
180        }
181    }
182
183    /// Writes the events of the driver.
184    ///
185    /// Returns `false` if the driver was paused as the output holds at
186    /// least `limit` bytes that are final.  With a limit of `usize::MAX`
187    /// the value is written at once.
188    pub(crate) fn drive(
189        &mut self,
190        driver: &mut SerializeDriver<'_>,
191        limit: usize,
192    ) -> Result<bool, Error> {
193        self.accept_raw(driver);
194        if limit == usize::MAX {
195            return self.drive_whole(driver).map(|()| true);
196        }
197        self.limit = limit;
198        let done = driver.drive_until(self)?;
199        if done {
200            self.finish();
201        }
202        Ok(done)
203    }
204
205    /// Writes the events of the driver at once.
206    ///
207    /// Unlike `drive` this does not refer to the pausable instance of the
208    /// driver which is only needed by stream serializers.
209    pub(crate) fn drive_whole(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
210        self.accept_raw(driver);
211        driver.drive_sink(self)?;
212        self.finish();
213        Ok(())
214    }
215
216    #[inline(always)]
217    fn event(&mut self, event: Event, state: &State) -> Result<(), Error> {
218        match event {
219            Event::Atom(atom) => {
220                self.begin_item(state);
221                self.write_atom(atom)
222            }
223            Event::MapStart(shape) => self.start(true, shape, state),
224            Event::SeqStart(shape) => self.start(false, shape, state),
225            Event::MapEnd | Event::SeqEnd => self.end(),
226        }
227    }
228
229    /// Accounts for a new item in the current container and writes the
230    /// pending tags.
231    #[inline(always)]
232    fn begin_item(&mut self, state: &State) {
233        self.frame.remaining = self.frame.remaining.wrapping_sub(1);
234        if self.canonical && self.frame.is_map() {
235            self.offsets.push(self.out.len());
236        }
237        if let Some(tags) = state.event::<Tags>() {
238            self.write_tags(tags);
239        }
240    }
241
242    /// Writes the tags attached to the current event.
243    #[cold]
244    fn write_tags(&mut self, tags: &Tags) {
245        for &tag in tags.0.iter() {
246            self.write_head(MAJOR_TAG, tag);
247        }
248    }
249
250    #[inline(always)]
251    fn start(&mut self, is_map: bool, shape: ContainerShape, state: &State) -> Result<(), Error> {
252        self.begin_item(state);
253        let header = self.out.len();
254        let major = if is_map { MAJOR_MAP } else { MAJOR_ARRAY };
255        let mut info = (header << 2) | if is_map { IS_MAP } else { 0 };
256        // with a known length the header is written right away, otherwise a
257        // byte is reserved and the length is patched in at the end.
258        let remaining = match shape.len() {
259            Some(len) => {
260                self.write_head(major, len as u64);
261                if is_map { len as u64 * 2 } else { len as u64 }
262            }
263            None => {
264                self.out.push(major << 5);
265                info |= UNKNOWN_LEN;
266                self.open_unknown += 1;
267                u64::MAX
268            }
269        };
270        if self.canonical && is_map {
271            self.maps.push(CanonicalMap {
272                body: self.out.len(),
273                offsets_start: self.offsets.len(),
274            });
275        }
276        self.stack.push(core::mem::replace(
277            &mut self.frame,
278            Frame { remaining, info },
279        ));
280        Ok(())
281    }
282
283    #[inline(always)]
284    fn end(&mut self) -> Result<(), Error> {
285        let Some(parent) = self.stack.pop() else {
286            return Err(Error::new(ErrorKind::InvalidState, "unexpected end"));
287        };
288        let frame = core::mem::replace(&mut self.frame, parent);
289        if frame.remaining == 0 && !self.canonical {
290            Ok(())
291        } else {
292            self.end_slow(frame)
293        }
294    }
295
296    /// Ends a container that needs more than a check: the length was not
297    /// known upfront, the number of items does not match or maps in
298    /// canonical mode.
299    #[inline(never)]
300    fn end_slow(&mut self, frame: Frame) -> Result<(), Error> {
301        let unknown = frame.info & UNKNOWN_LEN != 0;
302        if !unknown && frame.remaining != 0 {
303            return Err(Error::new(
304                ErrorKind::InvalidState,
305                "number of items does not match the length of the container",
306            ));
307        }
308        let items = if unknown {
309            u64::MAX - frame.remaining
310        } else {
311            0
312        };
313        if frame.is_map() {
314            if !items.is_multiple_of(2) {
315                return Err(Error::new(ErrorKind::InvalidState, "map without value"));
316            }
317            if self.canonical {
318                let map = self.maps.pop().unwrap();
319                self.sort_entries(&map)?;
320            }
321        }
322        if unknown {
323            self.open_unknown -= 1;
324            let count = if frame.is_map() { items / 2 } else { items };
325            self.patch_length(frame.header(), count);
326        }
327        Ok(())
328    }
329
330    /// Patches the length of a container into the header.
331    ///
332    /// Only a single byte was reserved for the header.  If the length does
333    /// not fit, the remaining bytes of the header need to be inserted after
334    /// it.  Normally the insertions are deferred until the end so that the
335    /// output is only moved once.  In canonical mode the entries of maps are
336    /// moved when sorted, so the bytes are inserted immediately.
337    fn patch_length(&mut self, header: usize, count: u64) {
338        let major = self.out[header];
339        if count < 24 {
340            self.out[header] = major | count as u8;
341            return;
342        }
343        let mut buf = [0u8; 9];
344        let head = encode_head(&mut buf, major >> 5, count);
345        self.out[header] = head[0];
346        if self.canonical {
347            let extra = head.len() - 1;
348            let len = self.out.len();
349            self.out.resize(len + extra, 0);
350            self.out.copy_within(header + 1..len, header + 1 + extra);
351            self.out[header + 1..header + head.len()].copy_from_slice(&head[1..]);
352        } else {
353            self.insertions.push(Insertion {
354                offset: header + 1,
355                len: head.len() as u8 - 1,
356                bytes: {
357                    let mut bytes = [0; 8];
358                    bytes[..head.len() - 1].copy_from_slice(&head[1..]);
359                    bytes
360                },
361            });
362        }
363    }
364
365    /// Applies the deferred insertions.
366    #[cold]
367    fn apply_insertions(&mut self) {
368        self.insertions
369            .sort_unstable_by_key(|insertion| insertion.offset);
370        let extra: usize = self.insertions.iter().map(|x| x.len as usize).sum();
371        let mut src_end = self.out.len();
372        self.out.resize(src_end + extra, 0);
373        let mut dst_end = self.out.len();
374        // move the segments between the insertions from the back so that
375        // every byte is moved once.
376        for insertion in self.insertions.iter().rev() {
377            let segment = src_end - insertion.offset;
378            self.out
379                .copy_within(insertion.offset..src_end, dst_end - segment);
380            dst_end -= segment + insertion.len as usize;
381            self.out[dst_end..dst_end + insertion.len as usize]
382                .copy_from_slice(&insertion.bytes[..insertion.len as usize]);
383            src_end = insertion.offset;
384        }
385        debug_assert_eq!(src_end, dst_end);
386    }
387
388    /// Sorts the entries of a map for the deterministic encoding.
389    #[cold]
390    fn sort_entries(&mut self, map: &CanonicalMap) -> Result<(), Error> {
391        let offsets = self.offsets.split_off(map.offsets_start);
392        let body_start = map.body;
393        let body_end = self.out.len();
394        // (key start, value start, entry end)
395        let mut entries: Vec<(usize, usize, usize)> = (0..offsets.len())
396            .step_by(2)
397            .map(|idx| {
398                let end = offsets.get(idx + 2).copied().unwrap_or(body_end);
399                (offsets[idx], offsets[idx + 1], end)
400            })
401            .collect();
402        let out = &self.out;
403        entries.sort_by(|a, b| out[a.0..a.1].cmp(&out[b.0..b.1]));
404        if entries
405            .windows(2)
406            .any(|pair| out[pair[0].0..pair[0].1] == out[pair[1].0..pair[1].1])
407        {
408            return Err(Error::new(ErrorKind::DuplicateKey, "duplicate map key"));
409        }
410        let mut body = Vec::with_capacity(body_end - body_start);
411        for (start, _, end) in entries {
412            body.extend_from_slice(&out[start..end]);
413        }
414        self.out[body_start..body_end].copy_from_slice(&body);
415        Ok(())
416    }
417
418    #[inline(always)]
419    fn write_head(&mut self, major: u8, value: u64) {
420        if value < 24 {
421            self.out.push(major << 5 | value as u8);
422        } else {
423            let mut buf = [0u8; 9];
424            let head = encode_head(&mut buf, major, value);
425            extend(&mut self.out, head);
426        }
427    }
428
429    #[inline(always)]
430    fn write_atom(&mut self, atom: Atom) -> Result<(), Error> {
431        // borrowed strings and scalars do not need to be dropped, the atom
432        // is only dropped for the other values.
433        let atom = ManuallyDrop::new(atom);
434        match *atom {
435            Atom::Null => self.out.push(0xf6),
436            Atom::Bool(false) => self.out.push(0xf4),
437            Atom::Bool(true) => self.out.push(0xf5),
438            Atom::Str(ref val) if val.is_borrowed() => self.write_str(val),
439            Atom::Bytes(ref val) if val.is_borrowed() => self.write_bytes(val),
440            Atom::Char(c) => self.write_str(c.encode_utf8(&mut [0u8; 4])),
441            Atom::U64(val) => self.write_head(MAJOR_UNSIGNED, val),
442            Atom::I64(val) => self.write_i64(val),
443            Atom::F64(val) => self.write_f64(val),
444            Atom::F32(val) => self.write_f32(val),
445            _ => return self.write_other_atom(ManuallyDrop::into_inner(atom)),
446        }
447        Ok(())
448    }
449
450    #[inline(never)]
451    fn write_other_atom(&mut self, atom: Atom) -> Result<(), Error> {
452        match atom {
453            Atom::Str(ref val) | Atom::Lexical(ref val) => self.write_str(val),
454            Atom::Bytes(ref val) => self.write_bytes(val),
455            Atom::Ext(ref ext) => return self.write_ext(ext),
456            // values whose type was inferred from text are written as value
457            Atom::Implicit(ref val) => return self.write_atom(val.value().to_atom()),
458            _ => return Err(Error::new(ErrorKind::UnsupportedType, "unknown atom")),
459        }
460        Ok(())
461    }
462
463    #[inline(always)]
464    fn write_bytes(&mut self, val: &[u8]) {
465        self.write_head(MAJOR_BYTES, val.len() as u64);
466        extend(&mut self.out, val);
467    }
468
469    #[inline(always)]
470    fn write_str(&mut self, val: &str) {
471        self.write_head(MAJOR_TEXT, val.len() as u64);
472        extend(&mut self.out, val.as_bytes());
473    }
474
475    #[inline(always)]
476    fn write_i64(&mut self, val: i64) {
477        if val >= 0 {
478            self.write_head(MAJOR_UNSIGNED, val as u64);
479        } else {
480            // -1 - val without overflows
481            self.write_head(MAJOR_NEGATIVE, !val as u64);
482        }
483    }
484
485    /// Writes a float in the shortest form that preserves its value.
486    #[inline]
487    fn write_f64(&mut self, val: f64) {
488        // a value that fits into a half fits into a single
489        if f64::from(val as f32) == val {
490            self.write_f32(val as f32);
491        } else if val.is_nan() {
492            self.write_nan();
493        } else {
494            let mut buf = [0xfb; 9];
495            buf[1..].copy_from_slice(&val.to_be_bytes());
496            extend(&mut self.out, &buf);
497        }
498    }
499
500    /// Writes a single precision float in the shortest form that preserves
501    /// its value.
502    #[inline]
503    fn write_f32(&mut self, val: f32) {
504        if let Some(half) = f32_to_f16(val) {
505            let [a, b] = half.to_be_bytes();
506            extend(&mut self.out, &[0xf9, a, b]);
507        } else if val.is_nan() {
508            self.write_nan();
509        } else {
510            let mut buf = [0xfa; 5];
511            buf[1..].copy_from_slice(&val.to_be_bytes());
512            extend(&mut self.out, &buf);
513        }
514    }
515
516    /// Writes NaN, always as the canonical half precision NaN.
517    #[cold]
518    fn write_nan(&mut self) {
519        self.out.extend_from_slice(&[0xf9, 0x7e, 0x00]);
520    }
521
522    #[cold]
523    fn write_ext(&mut self, ext: &ExtValue) -> Result<(), Error> {
524        // raw CBOR is written as it is, the serialization only passes it on
525        // if it is (see `accept_raw`)
526        if let Some(raw) = ext.downcast_value_ref::<RawInput>()
527            && raw.is_format(&crate::raw::ID)
528        {
529            self.out.extend_from_slice(raw.as_bytes());
530        } else if let Some(&val) = ext.downcast_ref::<u128>() {
531            self.write_u128(val);
532        } else if let Some(&val) = ext.downcast_ref::<i128>() {
533            self.write_i128(val);
534        } else if let Some(val) = ext.downcast_ref::<BigInt>() {
535            self.write_bigint(val);
536        } else if let Some(val) = ext.downcast_ref::<Datetime>() {
537            if val.offset.is_some() {
538                // standard date/time string
539                self.write_head(MAJOR_TAG, 0);
540            } else if val.date.is_some() && val.time.is_none() {
541                // full-date string (RFC 8943)
542                self.write_head(MAJOR_TAG, 1004);
543            }
544            self.write_str(&val.to_string());
545        } else if let Some(val) = ext.downcast_ref::<Timestamp>() {
546            if val.nanosecond == 0 {
547                self.write_head(MAJOR_TAG, 1);
548                self.write_i64(val.seconds);
549            } else if let Some(datetime) = val.to_datetime() {
550                // date/time strings retain the precision
551                self.write_head(MAJOR_TAG, 0);
552                self.write_str(&datetime.to_string());
553            } else {
554                self.write_head(MAJOR_TAG, 1);
555                self.write_f64(val.as_secs_f64());
556            }
557        } else if let Some(val) = ext.downcast_ref::<Uuid>() {
558            self.write_head(MAJOR_TAG, 37);
559            self.write_bytes(&val.0);
560        } else if let Some(val) = ext.downcast_ref::<Decimal>() {
561            // decimal fraction: [exponent, mantissa]
562            let (mantissa, exponent) = val.to_parts();
563            self.write_head(MAJOR_TAG, 4);
564            self.write_head(MAJOR_ARRAY, 2);
565            self.write_i64(exponent);
566            self.write_bigint(&mantissa);
567        } else if let Some(&simple) = ext.downcast_ref::<Simple>() {
568            let value = simple.value();
569            if value < 24 {
570                self.out.push(0xe0 | value);
571            } else {
572                self.out.extend_from_slice(&[0xf8, value]);
573            }
574        } else {
575            match ext.fallback() {
576                Atom::Ext(_) => {
577                    return Err(Error::new(
578                        ErrorKind::UnsupportedType,
579                        "unsupported extension value",
580                    ));
581                }
582                fallback => return self.write_atom(fallback),
583            }
584        }
585        Ok(())
586    }
587
588    fn write_u128(&mut self, val: u128) {
589        match u64::try_from(val) {
590            Ok(val) => self.write_head(MAJOR_UNSIGNED, val),
591            Err(_) => self.write_bignum(2, val),
592        }
593    }
594
595    fn write_i128(&mut self, val: i128) {
596        if let Ok(val) = i64::try_from(val) {
597            self.write_i64(val);
598        } else if val >= 0 {
599            self.write_u128(val as u128);
600        } else {
601            // -1 - val without overflows
602            let magnitude = !val as u128;
603            match u64::try_from(magnitude) {
604                Ok(magnitude) => self.write_head(MAJOR_NEGATIVE, magnitude),
605                Err(_) => self.write_bignum(3, magnitude),
606            }
607        }
608    }
609
610    /// Writes an integer of any size in the shortest form.
611    fn write_bigint(&mut self, val: &BigInt) {
612        if let Some(val) = val.to_i128() {
613            self.write_i128(val);
614        } else if let Some(val) = val.to_u128() {
615            self.write_u128(val);
616        } else if val.is_negative() {
617            // negative bignums hold -1 - n
618            let mut magnitude = val.significant_magnitude().to_vec();
619            for byte in magnitude.iter_mut().rev() {
620                let (value, overflow) = byte.overflowing_sub(1);
621                *byte = value;
622                if !overflow {
623                    break;
624                }
625            }
626            let skip = magnitude.iter().take_while(|&&x| x == 0).count();
627            self.write_head(MAJOR_TAG, 3);
628            self.write_bytes(&magnitude[skip..]);
629        } else {
630            self.write_head(MAJOR_TAG, 2);
631            self.write_bytes(val.significant_magnitude());
632        }
633    }
634
635    /// Writes a bignum (tag 2 or 3) with the minimal number of bytes.
636    fn write_bignum(&mut self, tag: u64, val: u128) {
637        let bytes = val.to_be_bytes();
638        let skip = (val.leading_zeros() / 8) as usize;
639        self.write_head(MAJOR_TAG, tag);
640        self.write_head(MAJOR_BYTES, (bytes.len() - skip) as u64);
641        self.out.extend_from_slice(&bytes[skip..]);
642    }
643}
644
645/// Encodes the head of a data item into the buffer.
646#[inline]
647fn encode_head(buf: &mut [u8; 9], major: u8, value: u64) -> &[u8] {
648    let major = major << 5;
649    if value < 24 {
650        buf[0] = major | value as u8;
651        &buf[..1]
652    } else if value <= u64::from(u8::MAX) {
653        buf[0] = major | 24;
654        buf[1] = value as u8;
655        &buf[..2]
656    } else if value <= u64::from(u16::MAX) {
657        buf[0] = major | 25;
658        buf[1..3].copy_from_slice(&(value as u16).to_be_bytes());
659        &buf[..3]
660    } else if value <= u64::from(u32::MAX) {
661        buf[0] = major | 26;
662        buf[1..5].copy_from_slice(&(value as u32).to_be_bytes());
663        &buf[..5]
664    } else {
665        buf[0] = major | 27;
666        buf[1..9].copy_from_slice(&value.to_be_bytes());
667        &buf[..9]
668    }
669}
670
671impl SerializerConfig {
672    /// Creates the default configuration.
673    pub const fn new() -> SerializerConfig {
674        SerializerConfig {
675            canonical: false,
676            context: deser_core::Context::new(),
677        }
678    }
679
680    /// Returns a builder for the configuration (see [`SerializerConfigBuilder`]).
681    pub const fn builder() -> SerializerConfigBuilder {
682        SerializerConfigBuilder::new()
683    }
684
685    /// Returns a builder that starts with this configuration.
686    pub const fn into_builder(self) -> SerializerConfigBuilder {
687        SerializerConfigBuilder { value: self }
688    }
689
690    /// Sets the context the values are serialized in.
691    ///
692    /// The values of the context are the defaults of the extension values
693    /// of the state (see [`Context`](deser_core::Context)), for instance
694    /// the [`BytesFormat`](deser_core::BytesFormat).  The serializers and
695    /// writers created with the configuration use this context.  A context set on
696    /// the driver takes precedence.
697    pub fn set_context(&mut self, context: deser_core::Context) {
698        self.context = context;
699    }
700
701    /// Returns the context the values are serialized in.
702    pub fn context(&self) -> &deser_core::Context {
703        &self.context
704    }
705
706    /// Gives the context to a driver which has none.
707    #[inline]
708    fn apply_context(&self, driver: &mut SerializeDriver<'_>) {
709        if !self.context.is_empty() {
710            driver.set_default_context(self.context.clone());
711        }
712    }
713
714    /// Enables or disables the deterministic encoding.
715    ///
716    /// When enabled, the entries of maps are sorted by their encoded keys
717    /// (bytewise lexicographic order, RFC 8949 §4.2.1) and duplicate keys
718    /// are an error.  This makes the output independent of the iteration
719    /// order of maps such as `HashMap`.
720    pub const fn set_canonical(&mut self, yes: bool) {
721        self.canonical = yes;
722    }
723
724    /// Serializes the given value.
725    pub fn to_vec<T: Serialize + ?Sized>(&self, value: &T) -> Result<Vec<u8>, Error> {
726        self.to_vec_ref(SerializeRef::new(&value))
727    }
728
729    /// Serializes the given value with a configured driver.
730    ///
731    /// The callback is invoked with the driver before the serialization
732    /// starts, for instance to add [`Layer`](deser_core::ser::Layer)s.
733    pub fn to_vec_with<F, T: Serialize + ?Sized>(
734        &self,
735        value: &T,
736        setup: F,
737    ) -> Result<Vec<u8>, Error>
738    where
739        F: FnOnce(&mut SerializeDriver<'_>),
740    {
741        let mut driver = SerializeDriver::new(&value);
742        setup(&mut driver);
743        self.apply_context(&mut driver);
744        self.serialize_driver(&mut driver)
745    }
746
747    /// Serializes a value whose type is erased (see
748    /// [`to_vec`](Self::to_vec)).
749    ///
750    /// This is not generic: the code that exists for every type only
751    /// erases it.
752    fn to_vec_ref(&self, value: SerializeRef<'_>) -> Result<Vec<u8>, Error> {
753        let mut driver = SerializeDriver::from_ref(value);
754        self.apply_context(&mut driver);
755        self.serialize_driver(&mut driver)
756    }
757
758    /// Serializes (a part of) the value of a driver and appends the output
759    /// that is final.
760    ///
761    /// The progress of the value is kept in `item` (see
762    /// `StreamSerializer::drive_partial`), `true` is returned once the
763    /// value is complete.  If this fails, what was appended by the call is
764    /// removed from the output.
765    pub(crate) fn serialize_part(
766        &self,
767        item: &mut Option<Box<Writer>>,
768        driver: &mut SerializeDriver<'_>,
769        out: &mut Vec<u8>,
770        limit: usize,
771    ) -> Result<bool, Error> {
772        let len = out.len();
773        // a value that is written at once is written into the output
774        // directly without boxing the writer
775        if item.is_none() && limit == usize::MAX {
776            let mut writer = Writer::new(self.canonical, core::mem::take(out));
777            let rv = writer.drive(driver, usize::MAX);
778            *out = writer.out;
779            if rv.is_err() {
780                out.truncate(len);
781            }
782            return rv;
783        }
784        // the writer writes into an empty output directly, otherwise its
785        // output is appended
786        let adopt = out.is_empty();
787        let mut writer = item
788            .take()
789            .unwrap_or_else(|| Box::new(Writer::new(self.canonical, Vec::new())));
790        if adopt {
791            writer.out = core::mem::take(out);
792        }
793        // after an error the value is abandoned, its writer is dropped
794        let rv = writer.drive(driver, limit);
795        let output = core::mem::take(&mut writer.out);
796        if adopt {
797            *out = output;
798        } else if rv.is_ok() {
799            out.extend_from_slice(&output);
800        }
801        let done = match rv {
802            Ok(done) => done,
803            Err(err) => {
804                out.truncate(len);
805                return Err(err);
806            }
807        };
808        if !done {
809            *item = Some(writer);
810        }
811        Ok(done)
812    }
813
814    /// Serializes the value of a driver.
815    pub(crate) fn serialize_driver(
816        &self,
817        driver: &mut SerializeDriver<'_>,
818    ) -> Result<Vec<u8>, Error> {
819        let mut writer = Writer::new(self.canonical, Vec::with_capacity(128));
820        writer.drive_whole(driver)?;
821        Ok(writer.out)
822    }
823}
824
825/// Builds a [`SerializerConfig`].
826///
827/// The methods have the names of the setters of [`SerializerConfig`] (without `set_`).
828#[derive(Debug, Clone)]
829#[must_use]
830pub struct SerializerConfigBuilder {
831    value: SerializerConfig,
832}
833
834impl SerializerConfigBuilder {
835    /// Creates a builder that starts with the default.
836    pub const fn new() -> SerializerConfigBuilder {
837        SerializerConfigBuilder {
838            value: SerializerConfig::new(),
839        }
840    }
841
842    /// Enables or disables the deterministic encoding.
843    ///
844    /// See [`SerializerConfig::set_canonical`].
845    pub const fn canonical(mut self, yes: bool) -> SerializerConfigBuilder {
846        self.value.set_canonical(yes);
847        self
848    }
849
850    /// Sets the context the values are serialized in.
851    ///
852    /// See [`SerializerConfig::set_context`].
853    pub fn context(mut self, context: deser_core::Context) -> SerializerConfigBuilder {
854        self.value.set_context(context);
855        self
856    }
857
858    /// Returns the built [`SerializerConfig`].
859    pub const fn build(self) -> SerializerConfig {
860        // the value cannot be moved out of the builder in a const fn as the
861        // builder needs dropping (the context has a destructor)
862        // SAFETY: the value is read once and the builder is forgotten
863        let value = unsafe { core::ptr::read(&self.value) };
864        core::mem::forget(self);
865        value
866    }
867}
868
869impl Default for SerializerConfigBuilder {
870    fn default() -> SerializerConfigBuilder {
871        SerializerConfigBuilder::new()
872    }
873}
874
875/// Serializes values into CBOR.
876///
877/// Every call to [`serialize`](Self::serialize) writes a data item, the
878/// items follow each other which makes the output a [CBOR
879/// sequence](https://www.rfc-editor.org/rfc/rfc8742).
880///
881/// ```
882/// use deser_cbor::Serializer;
883///
884/// let mut serializer = Serializer::new();
885/// serializer.serialize(&1u32).unwrap();
886/// serializer.serialize(&"hi").unwrap();
887/// assert_eq!(serializer.finish(), [0x01, 0x62, b'h', b'i']);
888/// ```
889///
890/// The serializer is also the stream serializer of CBOR (see
891/// [`StreamSerializer`](ser::StreamSerializer)): the output can be taken
892/// while values are written, and large values can be written in parts.
893/// The output of arrays and maps whose length is not known upfront (and of
894/// maps in canonical mode) is held back until they are complete, as their
895/// header or the order of their entries is only known then.  To write to
896/// a [`Write`](std::io::Write) use [`SerializerConfig::writer`].
897pub struct Serializer {
898    config: SerializerConfig,
899    out: Vec<u8>,
900    written: usize,
901    // the value that is written in parts
902    item: Option<Box<Writer>>,
903    // a value was started with `drive_partial` and is not complete
904    in_progress: bool,
905}
906
907impl Default for Serializer {
908    fn default() -> Serializer {
909        Serializer::new()
910    }
911}
912
913impl Clone for Serializer {
914    /// Clones the serializer.
915    ///
916    /// The clone of a serializer that writes a value in parts cannot write
917    /// more values (see
918    /// [`StreamSerializer::in_progress`](ser::StreamSerializer::in_progress)).
919    fn clone(&self) -> Serializer {
920        Serializer {
921            config: self.config.clone(),
922            out: self.out.clone(),
923            written: self.written,
924            item: None,
925            in_progress: self.in_progress,
926        }
927    }
928}
929
930impl core::fmt::Debug for Serializer {
931    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
932        f.debug_struct("Serializer")
933            .field("config", &self.config)
934            .field("output", &self.out)
935            .field("written", &self.written)
936            .field("in_progress", &self.in_progress)
937            .finish()
938    }
939}
940
941impl Serializer {
942    /// Creates a serializer.
943    pub fn new() -> Serializer {
944        Serializer::with_config(SerializerConfig::new())
945    }
946
947    /// Creates a serializer with the given configuration.
948    pub fn with_config(config: SerializerConfig) -> Serializer {
949        Serializer {
950            config,
951            out: Vec::new(),
952            written: 0,
953            item: None,
954            in_progress: false,
955        }
956    }
957
958    /// Returns the configuration.
959    pub fn config(&self) -> &SerializerConfig {
960        &self.config
961    }
962
963    /// Returns the number of values that were written.
964    pub fn written(&self) -> usize {
965        self.written
966    }
967
968    /// Serializes a value.
969    ///
970    /// If the value fails to serialize, nothing is written.
971    pub fn serialize<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
972        ser::Serializer::serialize(self, value)
973    }
974
975    /// Serializes a value with a configured driver.
976    ///
977    /// The callback is invoked with the driver before the value is
978    /// serialized, for instance to add [`Layer`](deser_core::ser::Layer)s.
979    pub fn serialize_with<F, T: Serialize + ?Sized>(
980        &mut self,
981        value: &T,
982        setup: F,
983    ) -> Result<(), Error>
984    where
985        F: FnOnce(&mut SerializeDriver<'_>),
986    {
987        ser::Serializer::serialize_with(self, value, setup)
988    }
989
990    /// Returns the output written so far (that was not cleared).
991    pub fn output(&self) -> &[u8] {
992        &self.out
993    }
994
995    /// Returns the output.
996    pub fn finish(self) -> Vec<u8> {
997        self.out
998    }
999}
1000
1001impl ser::Serializer for Serializer {
1002    fn drive(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
1003        // only `drive_partial` continues a value
1004        if self.in_progress {
1005            return Err(Error::in_progress());
1006        }
1007        ser::StreamSerializer::drive_partial(self, driver, usize::MAX).map(|_| ())
1008    }
1009}
1010
1011impl ser::StreamSerializer for Serializer {
1012    fn output(&self) -> &[u8] {
1013        &self.out
1014    }
1015
1016    fn clear_output(&mut self) {
1017        self.out.clear();
1018    }
1019
1020    fn supports_partial(&self) -> bool {
1021        true
1022    }
1023
1024    fn drive_partial(
1025        &mut self,
1026        driver: &mut SerializeDriver<'_>,
1027        limit: usize,
1028    ) -> Result<bool, Error> {
1029        if !self.config.context.is_empty() {
1030            driver.set_default_context(self.config.context.clone());
1031        }
1032        if self.item.is_none() && self.in_progress {
1033            return Err(Error::in_progress());
1034        }
1035        // the parts of a value that failed stay written (see
1036        // `in_progress`)
1037        if !self
1038            .config
1039            .serialize_part(&mut self.item, driver, &mut self.out, limit)?
1040        {
1041            self.in_progress = true;
1042            return Ok(false);
1043        }
1044        self.in_progress = false;
1045        self.written += 1;
1046        Ok(true)
1047    }
1048
1049    fn in_progress(&self) -> bool {
1050        self.in_progress
1051    }
1052}
1053
1054#[cfg(feature = "io")]
1055impl SerializerConfig {
1056    /// Creates a writer of CBOR data items to a stream
1057    /// (see [`deser::io::Writer`](deser_core::io::Writer)).
1058    ///
1059    /// The items follow each other which makes the stream a [CBOR
1060    /// sequence](https://www.rfc-editor.org/rfc/rfc8742).
1061    ///
1062    /// ```
1063    /// use deser_cbor::SerializerConfig;
1064    ///
1065    /// let mut writer = SerializerConfig::new().writer(Vec::new());
1066    /// writer.write(&1u32).unwrap();
1067    /// writer.write(&"hi").unwrap();
1068    /// assert_eq!(writer.into_inner(), [0x01, 0x62, b'h', b'i']);
1069    /// ```
1070    pub fn writer<W: std::io::Write>(&self, writer: W) -> deser_core::io::Writer<W, Serializer> {
1071        deser_core::io::Writer::new(writer, Serializer::with_config(self.clone()))
1072    }
1073
1074    /// Serializes a value to a writer.
1075    ///
1076    /// See [`to_writer`].
1077    pub fn to_writer<W: std::io::Write, T: Serialize + ?Sized>(
1078        &self,
1079        writer: W,
1080        value: &T,
1081    ) -> Result<(), Error> {
1082        self.writer(writer).write(value)
1083    }
1084}
1085
1086/// Serializes a value to a writer.
1087///
1088/// The output of large values is written in pieces while they are
1089/// serialized (see [`deser::io`](deser_core::io)), the writer does not need to be
1090/// buffered.
1091///
1092/// ```
1093/// let mut out = Vec::new();
1094/// deser_cbor::to_writer(&mut out, &vec![1u32, 2]).unwrap();
1095/// assert_eq!(out, [0x82, 0x01, 0x02]);
1096/// ```
1097#[cfg(feature = "io")]
1098pub fn to_writer<W: std::io::Write, T: Serialize + ?Sized>(
1099    writer: W,
1100    value: &T,
1101) -> Result<(), Error> {
1102    SerializerConfig::new().to_writer(writer, value)
1103}
1104
1105/// Serializes a value to CBOR.
1106///
1107/// This uses the default [`SerializerConfig`].
1108pub fn to_vec<T: Serialize + ?Sized>(value: &T) -> Result<Vec<u8>, Error> {
1109    SerializerConfig::new().to_vec(value)
1110}