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