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