Skip to main content

deser_msgpack/
ser.rs

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