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