Skip to main content

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