messagepack_serde/ser/
mod.rs

1//!  Serialize support for messagepack
2//!
3//! ## Limitation
4//!
5//! MessagePack requires the length header of arrays and maps to be written
6//! before any elements are encoded. Therefore this serializer needs serde
7//! to provide the exact length up front. If serde calls
8//! `serialize_seq(None)` or `serialize_map(None)`, this serializer returns
9//! `Error::SeqLenNone`.
10//!
11//! Examples with `serde(flatten)`:
12//!
13//! ```rust
14//! use serde::Serialize;
15//! use std::collections::HashMap;
16//!
17//! // Fails
18//! #[derive(Serialize)]
19//! struct Inner { b: u8, c: u8 }
20//!
21//! #[derive(Serialize)]
22//! struct Outer {
23//!     a: u8,
24//!     #[serde(flatten)]
25//!     extra: Inner,
26//! }
27//!
28//! let mut buf = [0u8; 32];
29//! let v = Outer { a: 1, extra: Inner { b: 2, c: 3 } };
30//! let err = messagepack_serde::ser::to_slice(&v, &mut buf).unwrap_err();
31//! assert_eq!(err, messagepack_serde::ser::Error::SeqLenNone);
32//! ```
33//!
34
35mod error;
36mod map;
37mod num;
38mod seq;
39pub use num::{AggressiveMinimize, Exact, LosslessMinimize, NumEncoder};
40
41use core::marker::PhantomData;
42
43use crate::value::extension::{EXTENSION_STRUCT_NAME, SerializeExt};
44pub use error::Error;
45
46use messagepack_core::{
47    Encode, SliceWriter,
48    encode::{BinaryEncoder, MapFormatEncoder, NilEncoder, array::ArrayFormatEncoder},
49    io::{IoWrite, WError},
50};
51
52use serde::ser;
53
54#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
55struct Serializer<'a, W, Num> {
56    writer: &'a mut W,
57    current_length: usize,
58    num_encoder: PhantomData<Num>,
59}
60
61impl<'a, W, Num> Serializer<'a, W, Num>
62where
63    W: IoWrite,
64    Num: num::NumEncoder<W>,
65{
66    pub fn new(writer: &'a mut W, _num_encoder: Num) -> Self {
67        Self {
68            writer,
69            current_length: 0,
70            num_encoder: PhantomData,
71        }
72    }
73}
74
75impl<W, Num> AsMut<Self> for Serializer<'_, W, Num> {
76    fn as_mut(&mut self) -> &mut Self {
77        self
78    }
79}
80
81/// Serialize value as messagepack
82pub fn to_slice<T>(value: &T, buf: &mut [u8]) -> Result<usize, Error<WError>>
83where
84    T: ser::Serialize + ?Sized,
85{
86    to_slice_with_config(value, buf, num::LosslessMinimize)
87}
88
89/// Serialize value as messagepack with config.
90pub fn to_slice_with_config<'a, T, C>(
91    value: &T,
92    buf: &'a mut [u8],
93    config: C,
94) -> Result<usize, Error<WError>>
95where
96    T: ser::Serialize + ?Sized,
97    C: NumEncoder<SliceWriter<'a>>,
98{
99    let mut writer = SliceWriter::from_slice(buf);
100    let mut ser = Serializer::new(&mut writer, config);
101    value.serialize(&mut ser)?;
102    Ok(ser.current_length)
103}
104
105/// Serialize value as messagepack byte vector
106#[cfg(feature = "alloc")]
107pub fn to_vec<T>(value: &T) -> Result<alloc::vec::Vec<u8>, Error<core::convert::Infallible>>
108where
109    T: ser::Serialize + ?Sized,
110{
111    to_vec_with_config(value, num::LosslessMinimize)
112}
113
114/// Serialize value as messagepack byte vector with config
115#[cfg(feature = "alloc")]
116pub fn to_vec_with_config<T, C>(
117    value: &T,
118    config: C,
119) -> Result<alloc::vec::Vec<u8>, Error<core::convert::Infallible>>
120where
121    T: ser::Serialize + ?Sized,
122    C: NumEncoder<messagepack_core::io::VecWriter>,
123{
124    let mut writer = messagepack_core::io::VecWriter::new();
125    let mut ser = Serializer::new(&mut writer, config);
126    value.serialize(&mut ser)?;
127    let buf = writer.into_vec();
128    Ok(buf)
129}
130
131#[cfg(feature = "std")]
132/// Serialize value as messagepack
133pub fn to_writer<T, W>(value: &T, writer: &mut W) -> Result<usize, Error<std::io::Error>>
134where
135    T: ser::Serialize + ?Sized,
136    W: std::io::Write,
137{
138    to_writer_with_config(value, writer, num::LosslessMinimize)
139}
140
141#[cfg(feature = "std")]
142/// Serialize value as messagepack with config.
143pub fn to_writer_with_config<T, W, C>(
144    value: &T,
145    writer: &mut W,
146    config: C,
147) -> Result<usize, Error<std::io::Error>>
148where
149    T: ser::Serialize + ?Sized,
150    W: std::io::Write,
151    C: NumEncoder<W>,
152{
153    let mut ser = Serializer::new(writer, config);
154    value.serialize(&mut ser)?;
155    Ok(ser.current_length)
156}
157
158impl<'a, 'b: 'a, W, Num> ser::Serializer for &'a mut Serializer<'b, W, Num>
159where
160    W: IoWrite,
161    Num: NumEncoder<W>,
162{
163    type Ok = ();
164    type Error = Error<W::Error>;
165
166    type SerializeSeq = seq::SerializeSeq<'a, 'b, W, Num>;
167    type SerializeTuple = seq::SerializeSeq<'a, 'b, W, Num>;
168    type SerializeTupleStruct = seq::SerializeSeq<'a, 'b, W, Num>;
169    type SerializeTupleVariant = seq::SerializeSeq<'a, 'b, W, Num>;
170    type SerializeMap = map::SerializeMap<'a, 'b, W, Num>;
171    type SerializeStruct = map::SerializeMap<'a, 'b, W, Num>;
172    type SerializeStructVariant = map::SerializeMap<'a, 'b, W, Num>;
173
174    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
175        self.current_length += v.encode(self.writer)?;
176        Ok(())
177    }
178
179    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
180        self.current_length += Num::encode_i8(v, self.writer)?;
181        Ok(())
182    }
183
184    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
185        self.current_length += Num::encode_i16(v, self.writer)?;
186        Ok(())
187    }
188
189    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
190        self.current_length += Num::encode_i32(v, self.writer)?;
191        Ok(())
192    }
193
194    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
195        self.current_length += Num::encode_i64(v, self.writer)?;
196        Ok(())
197    }
198
199    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
200        self.current_length += Num::encode_i128(v, self.writer)?;
201        Ok(())
202    }
203
204    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
205        self.current_length += Num::encode_u8(v, self.writer)?;
206        Ok(())
207    }
208
209    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
210        self.current_length += Num::encode_u16(v, self.writer)?;
211        Ok(())
212    }
213
214    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
215        self.current_length += Num::encode_u32(v, self.writer)?;
216        Ok(())
217    }
218
219    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
220        self.current_length += Num::encode_u64(v, self.writer)?;
221        Ok(())
222    }
223
224    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
225        self.current_length += Num::encode_u128(v, self.writer)?;
226        Ok(())
227    }
228
229    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
230        self.current_length += Num::encode_f32(v, self.writer)?;
231        Ok(())
232    }
233
234    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
235        self.current_length += Num::encode_f64(v, self.writer)?;
236        Ok(())
237    }
238
239    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
240        // char takes max 4 bytes
241        let mut buf = [0u8; 4];
242        let s = v.encode_utf8(&mut buf);
243        self.serialize_str(s)
244    }
245
246    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
247        self.current_length += v.encode(self.writer)?;
248        Ok(())
249    }
250
251    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
252        self.current_length += BinaryEncoder(v).encode(self.writer)?;
253        Ok(())
254    }
255
256    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
257        self.current_length += NilEncoder.encode(self.writer)?;
258        Ok(())
259    }
260
261    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
262    where
263        T: ?Sized + ser::Serialize,
264    {
265        value.serialize(self)
266    }
267
268    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
269        self.serialize_none()
270    }
271
272    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
273        self.serialize_unit()
274    }
275
276    fn serialize_unit_variant(
277        self,
278        _name: &'static str,
279        _variant_index: u32,
280        variant: &'static str,
281    ) -> Result<Self::Ok, Self::Error> {
282        self.serialize_str(variant)
283    }
284
285    fn serialize_newtype_struct<T>(
286        self,
287        name: &'static str,
288        value: &T,
289    ) -> Result<Self::Ok, Self::Error>
290    where
291        T: ?Sized + ser::Serialize,
292    {
293        match name {
294            EXTENSION_STRUCT_NAME => {
295                let mut ser = SerializeExt::new(self.writer);
296                value.serialize(&mut ser)?;
297                self.current_length += ser.length();
298                Ok(())
299            }
300            _ => value.serialize(self.as_mut()),
301        }
302    }
303
304    fn serialize_newtype_variant<T>(
305        self,
306        _name: &'static str,
307        _variant_index: u32,
308        variant: &'static str,
309        value: &T,
310    ) -> Result<Self::Ok, Self::Error>
311    where
312        T: ?Sized + ser::Serialize,
313    {
314        self.current_length += MapFormatEncoder::new(1).encode(self.writer)?;
315        self.serialize_str(variant)?;
316        value.serialize(self.as_mut())
317    }
318
319    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
320        let len = len.ok_or(Error::SeqLenNone)?;
321        self.current_length += ArrayFormatEncoder(len).encode(self.writer)?;
322        Ok(seq::SerializeSeq::new(self))
323    }
324
325    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
326        self.serialize_seq(Some(len))
327    }
328
329    fn serialize_tuple_struct(
330        self,
331        _name: &'static str,
332        len: usize,
333    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
334        self.serialize_seq(Some(len))
335    }
336
337    fn serialize_tuple_variant(
338        self,
339        _name: &'static str,
340        _variant_index: u32,
341        variant: &'static str,
342        len: usize,
343    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
344        self.current_length += MapFormatEncoder::new(1).encode(self.writer)?;
345        self.serialize_str(variant)?;
346        self.current_length += ArrayFormatEncoder(len).encode(self.writer)?;
347        Ok(seq::SerializeSeq::new(self))
348    }
349
350    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
351        let len = len.ok_or(Error::SeqLenNone)?;
352        self.current_length += MapFormatEncoder::new(len).encode(self.writer)?;
353        Ok(map::SerializeMap::new(self))
354    }
355
356    fn serialize_struct(
357        self,
358        _name: &'static str,
359        len: usize,
360    ) -> Result<Self::SerializeStruct, Self::Error> {
361        self.current_length += MapFormatEncoder::new(len).encode(self.writer)?;
362        Ok(map::SerializeMap::new(self))
363    }
364
365    fn serialize_struct_variant(
366        self,
367        name: &'static str,
368        _variant_index: u32,
369        variant: &'static str,
370        len: usize,
371    ) -> Result<Self::SerializeStructVariant, Self::Error> {
372        self.current_length += MapFormatEncoder::new(1).encode(self.writer)?;
373        self.serialize_str(variant)?;
374        self.serialize_struct(name, len)
375    }
376
377    #[cfg(not(any(feature = "alloc", feature = "std")))]
378    fn collect_str<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
379    where
380        T: ?Sized + core::fmt::Display,
381    {
382        Err(ser::Error::custom("`collect_str` is not supported"))
383    }
384
385    fn is_human_readable(&self) -> bool {
386        false
387    }
388}
389
390#[cfg(test)]
391mod tests {
392    use serde::Serialize;
393
394    use super::*;
395
396    #[test]
397    fn encode_nil() {
398        let v: Option<()> = None;
399        let buf = &mut [0u8; 128];
400        let len = to_slice(&v, buf).unwrap();
401        assert_eq!(buf[..len], [0xc0]);
402    }
403
404    #[test]
405    fn encode_unit() {
406        let buf = &mut [0u8; 128];
407        let len = to_slice(&(), buf).unwrap();
408        assert_eq!(buf[..len], [0xc0]);
409    }
410
411    #[test]
412    fn encode_unit_struct() {
413        #[derive(Serialize)]
414        struct Unit;
415        let buf = &mut [0u8; 128];
416        let len = to_slice(&Unit, buf).unwrap();
417        assert_eq!(buf[..len], [0xc0]);
418    }
419
420    #[test]
421    fn encode_false() {
422        let v = false;
423        let buf = &mut [0u8; 128];
424        let len = to_slice(&v, buf).unwrap();
425        assert_eq!(buf[..len], [0xc2]);
426    }
427
428    #[test]
429    fn encode_true() {
430        let v = true;
431        let buf = &mut [0u8; 128];
432        let len = to_slice(&v, buf).unwrap();
433        assert_eq!(buf[..len], [0xc3]);
434    }
435
436    #[test]
437    fn encode_bytes() {
438        // default &[u8] not call serialize_bytes
439        let v = serde_bytes::Bytes::new(&[5, 4, 3, 2, 1, 0]);
440
441        let buf = &mut [0u8; 128];
442        let len = to_slice(&v, buf).unwrap();
443        assert_eq!(buf[..len], [0xc4, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00]);
444    }
445
446    #[test]
447    fn encode_enum() {
448        #[derive(Serialize)]
449        enum Type {
450            Bool,
451            Int,
452            Float,
453        }
454        let buf = &mut [0u8; 128];
455        {
456            let len = to_slice(&Type::Bool, buf).unwrap();
457            assert_eq!(buf[..len], [0xa4, b'B', b'o', b'o', b'l'])
458        }
459        {
460            let len = to_slice(&Type::Int, buf).unwrap();
461            assert_eq!(buf[..len], [0xa3, b'I', b'n', b't'])
462        }
463        {
464            let len = to_slice(&Type::Float, buf).unwrap();
465            assert_eq!(buf[..len], [0xa5, b'F', b'l', b'o', b'a', b't'])
466        }
467    }
468
469    #[test]
470    fn encode_newtype_struct() {
471        #[derive(Serialize)]
472        struct B(#[serde(with = "serde_bytes")] [u8; 5]);
473
474        let buf = &mut [0u8; 128];
475
476        let len = to_slice(&B([5, 4, 3, 2, 1]), buf).unwrap();
477        assert_eq!(buf[..len], [0xc4, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01])
478    }
479
480    #[test]
481    fn encode_newtype_variant() {
482        #[derive(Serialize)]
483        enum Type {
484            Bool(bool),
485            Int(u8),
486            Float(f32),
487        }
488
489        let buf = &mut [0u8; 128];
490        {
491            let len = to_slice(&Type::Bool(true), buf).unwrap();
492            assert_eq!(
493                buf[..len],
494                [
495                    0x81, // fixmap len = 1
496                    0xa4, // fixstr len = 4
497                    b'B', b'o', b'o', b'l', 0xc3 // true
498                ]
499            )
500        }
501        {
502            let len = to_slice(&Type::Int(128), buf).unwrap();
503            assert_eq!(
504                buf[..len],
505                [
506                    0x81, // fixmap len = 1
507                    0xa3, b'I', b'n', b't', // fixstr "Int"
508                    0xcc, 0x80 // uint8 128
509                ]
510            )
511        }
512
513        {
514            let len = to_slice(&Type::Float(12.34), buf).unwrap();
515            assert_eq!(
516                buf[..len],
517                [
518                    0x81, // fixmap len = 1
519                    0xa5, b'F', b'l', b'o', b'a', b't', // fixstr "Float"
520                    0xca, 0x41, 0x45, 0x70, 0xa4 // float32 12.34
521                ]
522            )
523        }
524    }
525
526    #[test]
527    fn encode_struct_variant() {
528        #[derive(Serialize)]
529        enum Type {
530            Bool { flag: bool, msg: &'static str },
531        }
532
533        // expect
534        // {
535        //   "Bool":{
536        //       "flag": bool,
537        //       "msg": "Some message"
538        //    }
539        // }
540
541        let buf = &mut [0u8; 128];
542        {
543            let len = to_slice(
544                &Type::Bool {
545                    flag: false,
546                    msg: "hi",
547                },
548                buf,
549            )
550            .unwrap();
551            assert_eq!(
552                buf[..len],
553                [
554                    0x81, // fixmap len = 1
555                    0xa4, // fixstr len = 4
556                    b'B', b'o', b'o', b'l', // top
557                    0x82, // fixmap len = 2
558                    0xa4, // fixstr len = 4
559                    b'f', b'l', b'a', b'g', // key
560                    0xc2, // false
561                    0xa3, // fixstr len = 3
562                    b'm', b's', b'g', //key
563                    0xa2, // fixstr len = 2
564                    b'h', b'i',
565                ]
566            )
567        }
568    }
569
570    #[test]
571    fn encode_tuple_struct() {
572        #[derive(Serialize)]
573        struct V(i16, u32, i32);
574
575        let buf = &mut [0u8; 128];
576        let len = to_slice(&V(1, 2, 3), buf).unwrap();
577        assert_eq!(
578            buf[..len],
579            [
580                0x93, // fixarr len = 3
581                0x01, // positive fixint 1
582                0x02, // positive fixint 2
583                0x03, // positive fixint 3
584            ]
585        );
586    }
587
588    #[test]
589    fn encode_pos_fix_int() {
590        let v = 127_u8;
591        let buf = &mut [0u8; 128];
592        let len = to_slice(&v, buf).unwrap();
593        assert_eq!(buf[..len], [0x7f]);
594    }
595
596    #[test]
597    fn encode_neg_fix_int() {
598        let v = -32_i8;
599        let buf = &mut [0u8; 128];
600        let len = to_slice(&v, buf).unwrap();
601        assert_eq!(buf[..len], [0xe0]);
602    }
603
604    #[cfg(feature = "std")]
605    #[test]
606    fn encode_with_writer() {
607        #[derive(Serialize)]
608        struct V(i16, u32, i32);
609
610        let mut buf = vec![];
611        let len = to_writer(&V(1, 2, 3), &mut buf).unwrap();
612        assert_eq!(
613            buf[..len],
614            [
615                0x93, // fixarr len = 3
616                0x01, // positive fixint 1
617                0x02, // positive fixint 2
618                0x03  // positive fixint 3
619            ]
620        );
621    }
622}