serde_json_wasm/ser/
mod.rs

1//! Serialize a Rust data structure into JSON data
2
3use alloc::string::{String, ToString};
4use alloc::vec::Vec;
5
6use serde::ser;
7
8use self::map::SerializeMap;
9use self::seq::SerializeSeq;
10use self::struct_::SerializeStruct;
11
12mod map;
13mod seq;
14mod struct_;
15
16/// Serialization result
17pub type Result<T> = ::core::result::Result<T, Error>;
18
19/// This type represents all possible errors that can occur when serializing JSON data
20///
21/// It implements [`std::error::Error`] trait so long as either `std` or
22/// `unstable` features are enabled.  `std` is enabled by default and disabling
23/// it makes the crate `no_std`.  `unstable` makes it necessary to build code
24/// with nightly compiler.
25#[derive(Debug)]
26#[non_exhaustive]
27pub enum Error {
28    /// Buffer is full
29    BufferFull,
30
31    /// Custom error message from serde
32    Custom(String),
33}
34
35impl From<()> for Error {
36    fn from(_: ()) -> Error {
37        Error::BufferFull
38    }
39}
40
41impl From<u8> for Error {
42    fn from(_: u8) -> Error {
43        Error::BufferFull
44    }
45}
46
47impl ser::StdError for Error {}
48
49impl core::fmt::Display for Error {
50    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51        match self {
52            Error::BufferFull => write!(f, "Buffer is full"),
53            Error::Custom(msg) => write!(f, "{}", &msg),
54        }
55    }
56}
57
58/// Serializer implements serde::ser::Serializer and allows us to serialize a
59/// serde struct into JSON
60pub struct Serializer {
61    buf: Vec<u8>,
62}
63
64/// Number of bytes reserved by default for the output JSON
65static INITIAL_CAPACITY: usize = 1024;
66
67impl Serializer {
68    fn new() -> Self {
69        Serializer {
70            buf: Vec::with_capacity(INITIAL_CAPACITY),
71        }
72    }
73}
74
75// NOTE(serialize_*signed) This is basically the numtoa implementation minus the lookup tables,
76// which take 200+ bytes of ROM / Flash
77macro_rules! serialize_unsigned {
78    ($self:ident, $N:expr, $v:expr) => {{
79        let mut buf = [0u8; $N];
80
81        let mut v = $v;
82        let mut i = $N - 1;
83        loop {
84            buf[i] = (v % 10) as u8 + b'0';
85            v /= 10;
86
87            if v == 0 {
88                break;
89            } else {
90                i -= 1;
91            }
92        }
93
94        $self.buf.extend_from_slice(&buf[i..]);
95        Ok(())
96    }};
97}
98// Export for use in map
99pub(crate) use serialize_unsigned;
100
101macro_rules! serialize_signed {
102    ($self:ident, $N:expr, $v:expr, $ixx:ident, $uxx:ident) => {{
103        let v = $v;
104        let (signed, mut v) = if v == $ixx::min_value() {
105            (true, $ixx::max_value() as $uxx + 1)
106        } else if v < 0 {
107            (true, -v as $uxx)
108        } else {
109            (false, v as $uxx)
110        };
111
112        let mut buf = [0u8; $N];
113        let mut i = $N - 1;
114        loop {
115            buf[i] = (v % 10) as u8 + b'0';
116            v /= 10;
117
118            i -= 1;
119
120            if v == 0 {
121                break;
122            }
123        }
124
125        if signed {
126            buf[i] = b'-';
127        } else {
128            i += 1;
129        }
130        $self.buf.extend_from_slice(&buf[i..]);
131        Ok(())
132    }};
133}
134// Export for use in map
135pub(crate) use serialize_signed;
136
137/// Upper-case hex for value in 0..16, encoded as ASCII bytes
138fn hex_4bit(c: u8) -> u8 {
139    if c <= 9 {
140        0x30 + c
141    } else {
142        0x41 + (c - 10)
143    }
144}
145
146/// Upper-case hex for value in 0..256, encoded as ASCII bytes
147fn hex(c: u8) -> (u8, u8) {
148    (hex_4bit(c >> 4), hex_4bit(c & 0x0F))
149}
150
151impl<'a> ser::Serializer for &'a mut Serializer {
152    type Ok = ();
153    type Error = Error;
154    type SerializeSeq = SerializeSeq<'a>;
155    type SerializeTuple = SerializeSeq<'a>;
156    type SerializeTupleStruct = Unreachable;
157    type SerializeTupleVariant = SerializeSeq<'a>;
158    type SerializeMap = SerializeMap<'a>;
159    type SerializeStruct = SerializeStruct<'a>;
160    type SerializeStructVariant = SerializeStruct<'a>;
161
162    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
163        if v {
164            self.buf.extend_from_slice(b"true");
165        } else {
166            self.buf.extend_from_slice(b"false");
167        }
168        Ok(())
169    }
170
171    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
172        // -128
173        serialize_signed!(self, 4, v, i8, u8)
174    }
175
176    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
177        // -32768
178        serialize_signed!(self, 6, v, i16, u16)
179    }
180
181    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
182        // -2147483648
183        serialize_signed!(self, 11, v, i32, u32)
184    }
185
186    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
187        // -9223372036854775808
188        serialize_signed!(self, 20, v, i64, u64)
189    }
190
191    fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
192        // -170141183460469231731687303715884105728
193        serialize_signed!(self, 40, v, i128, u128)
194    }
195
196    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
197        // 255
198        serialize_unsigned!(self, 3, v)
199    }
200
201    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
202        // 65535
203        serialize_unsigned!(self, 5, v)
204    }
205
206    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
207        // 4294967295
208        serialize_unsigned!(self, 10, v)
209    }
210
211    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
212        // 18446744073709551615
213        serialize_unsigned!(self, 20, v)
214    }
215
216    fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
217        // 340282366920938463463374607431768211455
218        serialize_unsigned!(self, 39, v)
219    }
220
221    fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
222        unreachable!()
223    }
224
225    fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
226        unreachable!()
227    }
228
229    fn serialize_char(self, _v: char) -> Result<Self::Ok> {
230        unreachable!()
231    }
232
233    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
234        self.buf.push(b'"');
235
236        // Do escaping according to "6. MUST represent all strings (including object member names) in
237        // their minimal-length UTF-8 encoding": https://gibson042.github.io/canonicaljson-spec/
238        //
239        // We don't need to escape lone surrogates because surrogate pairs do not exist in valid UTF-8,
240        // even if they can exist in JSON or JavaScript strings (UCS-2 based). As a result, lone surrogates
241        // cannot exist in a Rust String. If they do, the bug is in the String constructor.
242        // An excellent explanation is available at https://www.youtube.com/watch?v=HhIEDWmQS3w
243
244        // Temporary storage for encoded a single char.
245        // A char is up to 4 bytes long when encoded to UTF-8.
246        let mut encoding_tmp = [0u8; 4];
247
248        for c in v.chars() {
249            match c {
250                '\\' => {
251                    self.buf.push(b'\\');
252                    self.buf.push(b'\\');
253                }
254                '"' => {
255                    self.buf.push(b'\\');
256                    self.buf.push(b'"');
257                }
258                '\u{0008}' => {
259                    self.buf.push(b'\\');
260                    self.buf.push(b'b');
261                }
262                '\u{0009}' => {
263                    self.buf.push(b'\\');
264                    self.buf.push(b't');
265                }
266                '\u{000A}' => {
267                    self.buf.push(b'\\');
268                    self.buf.push(b'n');
269                }
270                '\u{000C}' => {
271                    self.buf.push(b'\\');
272                    self.buf.push(b'f');
273                }
274                '\u{000D}' => {
275                    self.buf.push(b'\\');
276                    self.buf.push(b'r');
277                }
278                '\u{0000}'..='\u{001F}' => {
279                    self.buf.push(b'\\');
280                    self.buf.push(b'u');
281                    self.buf.push(b'0');
282                    self.buf.push(b'0');
283                    let (hex1, hex2) = hex(c as u8);
284                    self.buf.push(hex1);
285                    self.buf.push(hex2);
286                }
287                _ => {
288                    if c.len_utf8() == 1 {
289                        self.buf.push(c as u8);
290                    } else {
291                        let encoded = c.encode_utf8(&mut encoding_tmp as &mut [u8]);
292                        self.buf.extend_from_slice(encoded.as_bytes());
293                    }
294                }
295            }
296        }
297
298        self.buf.push(b'"');
299        Ok(())
300    }
301
302    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
303        unreachable!()
304    }
305
306    fn serialize_none(self) -> Result<Self::Ok> {
307        self.buf.extend_from_slice(b"null");
308        Ok(())
309    }
310
311    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok>
312    where
313        T: ser::Serialize,
314    {
315        value.serialize(self)
316    }
317
318    fn serialize_unit(self) -> Result<Self::Ok> {
319        // The unit type is a zero element tuple, so the consistent way to serialize this would be "[]".
320        // However, for compatibility with serde_json we serialize to "null".
321        self.buf.extend_from_slice(b"null");
322        Ok(())
323    }
324
325    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
326        // Unit struct is serialized to (serde_json compatible) "null"
327        self.buf.extend_from_slice(b"null");
328        Ok(())
329    }
330
331    fn serialize_unit_variant(
332        self,
333        _name: &'static str,
334        _variant_index: u32,
335        variant: &'static str,
336    ) -> Result<Self::Ok> {
337        self.serialize_str(variant)
338    }
339
340    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
341    where
342        T: ser::Serialize,
343    {
344        value.serialize(&mut *self)
345    }
346
347    fn serialize_newtype_variant<T: ?Sized>(
348        self,
349        _name: &'static str,
350        _variant_index: u32,
351        variant: &'static str,
352        value: &T,
353    ) -> Result<Self::Ok>
354    where
355        T: ser::Serialize,
356    {
357        self.buf.push(b'{');
358        self.serialize_str(variant)?;
359        self.buf.push(b':');
360        value.serialize(&mut *self)?;
361        self.buf.push(b'}');
362        Ok(())
363    }
364
365    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
366        self.buf.push(b'[');
367
368        Ok(SerializeSeq::new(self))
369    }
370
371    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
372        self.serialize_seq(Some(_len))
373    }
374
375    fn serialize_tuple_struct(
376        self,
377        _name: &'static str,
378        _len: usize,
379    ) -> Result<Self::SerializeTupleStruct> {
380        unreachable!()
381    }
382
383    fn serialize_tuple_variant(
384        self,
385        _name: &'static str,
386        _variant_index: u32,
387        variant: &'static str,
388        len: usize,
389    ) -> Result<Self::SerializeTupleVariant> {
390        self.buf.push(b'{');
391        self.serialize_str(variant)?;
392        self.buf.push(b':');
393        self.serialize_tuple(len)
394    }
395
396    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
397        self.buf.push(b'{');
398        Ok(SerializeMap::new(self))
399    }
400
401    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
402        self.buf.push(b'{');
403
404        Ok(SerializeStruct::new(self))
405    }
406
407    fn serialize_struct_variant(
408        self,
409        name: &'static str,
410        _variant_index: u32,
411        variant: &'static str,
412        len: usize,
413    ) -> Result<Self::SerializeStructVariant> {
414        self.buf.push(b'{');
415        self.serialize_str(variant)?;
416        self.buf.push(b':');
417        self.serialize_struct(name, len)
418    }
419}
420
421/// Serializes the given data structure as a string of JSON text
422pub fn to_string<T>(value: &T) -> Result<String>
423where
424    T: ser::Serialize + ?Sized,
425{
426    let mut ser = Serializer::new();
427    value.serialize(&mut ser)?;
428    Ok(unsafe { String::from_utf8_unchecked(ser.buf) })
429}
430
431/// Serializes the given data structure as a JSON byte vector
432pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
433where
434    T: ser::Serialize + ?Sized,
435{
436    let mut ser = Serializer::new();
437    value.serialize(&mut ser)?;
438    Ok(ser.buf)
439}
440
441impl ser::Error for Error {
442    fn custom<T: core::fmt::Display>(msg: T) -> Self {
443        Error::Custom(msg.to_string())
444    }
445}
446
447/// Unreachable is a placeholder for features that are not supported
448/// (and should be unreachable, unless you use unsupported serde flags)
449pub enum Unreachable {}
450
451impl ser::SerializeTupleStruct for Unreachable {
452    type Ok = ();
453    type Error = Error;
454
455    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
456        unreachable!()
457    }
458
459    fn end(self) -> Result<Self::Ok> {
460        unreachable!()
461    }
462}
463
464impl ser::SerializeTupleVariant for Unreachable {
465    type Ok = ();
466    type Error = Error;
467
468    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
469        unreachable!()
470    }
471
472    fn end(self) -> Result<Self::Ok> {
473        unreachable!()
474    }
475}
476
477impl ser::SerializeMap for Unreachable {
478    type Ok = ();
479    type Error = Error;
480
481    fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<()>
482    where
483        T: ser::Serialize,
484    {
485        unreachable!()
486    }
487
488    fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<()>
489    where
490        T: ser::Serialize,
491    {
492        unreachable!()
493    }
494
495    fn end(self) -> Result<Self::Ok> {
496        unreachable!()
497    }
498}
499
500impl ser::SerializeStructVariant for Unreachable {
501    type Ok = ();
502    type Error = Error;
503
504    fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, _value: &T) -> Result<()>
505    where
506        T: ser::Serialize,
507    {
508        unreachable!()
509    }
510
511    fn end(self) -> Result<Self::Ok> {
512        unreachable!()
513    }
514}
515
516#[cfg(test)]
517mod tests {
518    use super::to_string;
519
520    use alloc::collections::BTreeMap;
521    use alloc::string::{String, ToString};
522    use alloc::vec;
523    use alloc::vec::Vec;
524    use std::collections::HashMap;
525
526    use serde::{Serialize, Serializer};
527    use serde_derive::{Deserialize, Serialize};
528
529    #[macro_export]
530    macro_rules! assert_serde_json_serialize_eq {
531        ($target:expr,) => {
532            assert_serde_json_serialize_eq!($target);
533        };
534        ($target:expr) => {
535            assert_eq!(
536                crate::to_string($target).unwrap(),
537                ::serde_json::to_string($target).unwrap(),
538                "Serialization does not match serde_json"
539            );
540        };
541    }
542
543    #[test]
544    fn bool() {
545        assert_eq!(to_string(&true).unwrap(), "true");
546        assert_eq!(to_string(&false).unwrap(), "false");
547    }
548
549    #[test]
550    fn number() {
551        assert_eq!(to_string::<u8>(&0).unwrap(), "0");
552        assert_eq!(to_string::<u8>(&1).unwrap(), "1");
553        assert_eq!(to_string::<u8>(&u8::MAX).unwrap(), "255");
554
555        assert_eq!(to_string::<i8>(&0).unwrap(), "0");
556        assert_eq!(to_string::<i8>(&1).unwrap(), "1");
557        assert_eq!(to_string::<i8>(&127).unwrap(), "127");
558        assert_eq!(to_string::<i8>(&-1).unwrap(), "-1");
559        assert_eq!(to_string::<i8>(&i8::MIN).unwrap(), "-128");
560
561        assert_eq!(to_string::<u16>(&0).unwrap(), "0");
562        assert_eq!(to_string::<u16>(&1).unwrap(), "1");
563        assert_eq!(to_string::<u16>(&550).unwrap(), "550");
564        assert_eq!(to_string::<u16>(&u16::MAX).unwrap(), "65535");
565
566        assert_eq!(to_string::<i16>(&0).unwrap(), "0");
567        assert_eq!(to_string::<i16>(&1).unwrap(), "1");
568        assert_eq!(to_string::<i16>(&550).unwrap(), "550");
569        assert_eq!(to_string::<i16>(&i16::MAX).unwrap(), "32767");
570        assert_eq!(to_string::<i16>(&-1).unwrap(), "-1");
571        assert_eq!(to_string::<i16>(&i16::MIN).unwrap(), "-32768");
572
573        assert_eq!(to_string::<u32>(&0).unwrap(), "0");
574        assert_eq!(to_string::<u32>(&1).unwrap(), "1");
575        assert_eq!(to_string::<u32>(&456789).unwrap(), "456789");
576        assert_eq!(to_string::<u32>(&u32::MAX).unwrap(), "4294967295");
577
578        assert_eq!(to_string::<i32>(&0).unwrap(), "0");
579        assert_eq!(to_string::<i32>(&1).unwrap(), "1");
580        assert_eq!(to_string::<i32>(&456789).unwrap(), "456789");
581        assert_eq!(to_string::<i32>(&i32::MAX).unwrap(), "2147483647");
582        assert_eq!(to_string::<i32>(&-1).unwrap(), "-1");
583        assert_eq!(to_string::<i32>(&i32::MIN).unwrap(), "-2147483648");
584
585        assert_eq!(to_string::<u64>(&0).unwrap(), "0");
586        assert_eq!(to_string::<u64>(&1).unwrap(), "1");
587        assert_eq!(to_string::<u64>(&456789).unwrap(), "456789");
588        assert_eq!(to_string::<u64>(&4294967295).unwrap(), "4294967295");
589        assert_eq!(to_string::<u64>(&4294967296).unwrap(), "4294967296");
590        assert_eq!(
591            to_string::<u64>(&9007199254740991).unwrap(),
592            "9007199254740991"
593        ); // Number.MAX_SAFE_INTEGER
594        assert_eq!(
595            to_string::<u64>(&9007199254740992).unwrap(),
596            "9007199254740992"
597        ); // Number.MAX_SAFE_INTEGER+1
598        assert_eq!(to_string::<u64>(&u64::MAX).unwrap(), "18446744073709551615");
599
600        assert_eq!(to_string::<i64>(&0).unwrap(), "0");
601        assert_eq!(to_string::<i64>(&1).unwrap(), "1");
602        assert_eq!(to_string::<i64>(&456789).unwrap(), "456789");
603        assert_eq!(to_string::<i64>(&4294967295).unwrap(), "4294967295");
604        assert_eq!(to_string::<i64>(&4294967296).unwrap(), "4294967296");
605        assert_eq!(
606            to_string::<i64>(&9007199254740991).unwrap(),
607            "9007199254740991"
608        ); // Number.MAX_SAFE_INTEGER
609        assert_eq!(
610            to_string::<i64>(&9007199254740992).unwrap(),
611            "9007199254740992"
612        ); // Number.MAX_SAFE_INTEGER+1
613        assert_eq!(to_string::<i64>(&i64::MAX).unwrap(), "9223372036854775807");
614        assert_eq!(to_string::<i64>(&-1).unwrap(), "-1");
615        assert_eq!(to_string::<i64>(&i64::MIN).unwrap(), "-9223372036854775808");
616
617        assert_eq!(to_string::<u128>(&0).unwrap(), r#"0"#);
618        assert_eq!(to_string::<u128>(&1).unwrap(), r#"1"#);
619        assert_eq!(to_string::<u128>(&456789).unwrap(), r#"456789"#);
620        assert_eq!(to_string::<u128>(&4294967295).unwrap(), r#"4294967295"#);
621        assert_eq!(to_string::<u128>(&4294967296).unwrap(), r#"4294967296"#);
622        assert_eq!(
623            to_string::<u128>(&9007199254740991).unwrap(),
624            r#"9007199254740991"#
625        ); // Number.MAX_SAFE_INTEGER
626        assert_eq!(
627            to_string::<u128>(&9007199254740992).unwrap(),
628            r#"9007199254740992"#
629        ); // Number.MAX_SAFE_INTEGER+1
630        assert_eq!(
631            to_string::<u128>(&9223372036854775807).unwrap(),
632            r#"9223372036854775807"#
633        );
634        assert_eq!(
635            to_string::<u128>(&9223372036854775808).unwrap(),
636            r#"9223372036854775808"#
637        );
638        assert_eq!(
639            to_string::<u128>(&u128::MAX).unwrap(),
640            r#"340282366920938463463374607431768211455"#
641        );
642        assert_serde_json_serialize_eq!(&u128::MAX);
643
644        assert_eq!(to_string::<i128>(&0).unwrap(), r#"0"#);
645        assert_eq!(to_string::<i128>(&1).unwrap(), r#"1"#);
646        assert_eq!(to_string::<i128>(&456789).unwrap(), r#"456789"#);
647        assert_eq!(to_string::<i128>(&4294967295).unwrap(), r#"4294967295"#);
648        assert_eq!(to_string::<i128>(&4294967296).unwrap(), r#"4294967296"#);
649        assert_eq!(
650            to_string::<i128>(&9007199254740991).unwrap(),
651            r#"9007199254740991"#
652        ); // Number.MAX_SAFE_INTEGER
653        assert_eq!(
654            to_string::<i128>(&9007199254740992).unwrap(),
655            r#"9007199254740992"#
656        ); // Number.MAX_SAFE_INTEGER+1
657        assert_eq!(
658            to_string::<i128>(&9223372036854775807).unwrap(),
659            r#"9223372036854775807"#
660        );
661        assert_eq!(
662            to_string::<i128>(&9223372036854775808).unwrap(),
663            r#"9223372036854775808"#
664        );
665        assert_eq!(
666            to_string::<i128>(&i128::MAX).unwrap(),
667            r#"170141183460469231731687303715884105727"#
668        );
669        assert_eq!(to_string::<i128>(&-1).unwrap(), r#"-1"#);
670        assert_eq!(
671            to_string::<i128>(&i128::MIN).unwrap(),
672            r#"-170141183460469231731687303715884105728"#
673        );
674        assert_serde_json_serialize_eq!(&i128::MIN);
675    }
676
677    #[test]
678    fn array() {
679        assert_eq!(to_string::<[u8]>(&[]).unwrap(), "[]");
680        assert_eq!(to_string(&[0, 1, 2]).unwrap(), "[0,1,2]");
681    }
682
683    #[test]
684    fn tuple() {
685        type Pair = (i64, i64);
686        type Wrapped = (i64,); // Comma differentiates one element tuple from a primary type surrounded by parentheses
687        type Unit = ();
688
689        let pair: Pair = (1, 2);
690        assert_eq!(to_string(&pair).unwrap(), "[1,2]");
691        assert_serde_json_serialize_eq!(&pair);
692
693        let wrapped: Wrapped = (5,);
694        assert_eq!(to_string(&wrapped).unwrap(), "[5]");
695        assert_serde_json_serialize_eq!(&wrapped);
696
697        #[allow(clippy::let_unit_value)]
698        let unit: Unit = ();
699        assert_eq!(to_string(&unit).unwrap(), "null");
700        assert_serde_json_serialize_eq!(&unit);
701
702        type BigPair = (u128, u128);
703
704        let pair: BigPair = (u128::MAX, u128::MAX);
705
706        assert_eq!(
707            to_string(&pair).unwrap(),
708            r#"[340282366920938463463374607431768211455,340282366920938463463374607431768211455]"#
709        );
710        assert_serde_json_serialize_eq!(&pair);
711    }
712
713    #[test]
714    fn enum_variants_unit_like() {
715        #[allow(dead_code)]
716        #[derive(Serialize)]
717        enum Op {
718            Enter,
719            Exit,
720        }
721        assert_eq!(to_string(&Op::Exit).unwrap(), r#""Exit""#);
722        assert_serde_json_serialize_eq!(&Op::Exit);
723
724        // Numeric values are ignored 🤷
725        #[derive(Serialize)]
726        enum Order {
727            Unordered = 1,
728            Ordered = 42,
729        }
730        assert_eq!(to_string(&Order::Unordered).unwrap(), r#""Unordered""#);
731        assert_serde_json_serialize_eq!(&Order::Unordered);
732
733        assert_eq!(to_string(&Order::Ordered).unwrap(), r#""Ordered""#);
734        assert_serde_json_serialize_eq!(&Order::Ordered);
735    }
736
737    #[test]
738    fn enum_variants_tuple_like_structs() {
739        #[derive(Serialize)]
740        enum Op {
741            Exit(),
742            Square(i32),
743            Add(i64, i64),
744        }
745        assert_eq!(to_string(&Op::Exit()).unwrap(), r#"{"Exit":[]}"#);
746        assert_serde_json_serialize_eq!(&Op::Exit());
747
748        assert_eq!(to_string(&Op::Square(2)).unwrap(), r#"{"Square":2}"#);
749        assert_serde_json_serialize_eq!(&Op::Square(2));
750
751        assert_eq!(to_string(&Op::Add(3, 4)).unwrap(), r#"{"Add":[3,4]}"#);
752        assert_serde_json_serialize_eq!(&Op::Add(3, 4));
753    }
754
755    #[test]
756    fn enum_variants_c_like_structs() {
757        #[derive(Serialize)]
758        enum Op {
759            Exit {},
760            Square { input: i32 },
761            Add { a: i64, b: i64 },
762        }
763        assert_eq!(to_string(&Op::Exit {}).unwrap(), r#"{"Exit":{}}"#);
764        assert_serde_json_serialize_eq!(&Op::Exit {});
765
766        assert_eq!(
767            to_string(&Op::Square { input: 2 }).unwrap(),
768            r#"{"Square":{"input":2}}"#
769        );
770        assert_serde_json_serialize_eq!(&Op::Square { input: 2 });
771
772        assert_eq!(
773            to_string(&Op::Add { a: 3, b: 4 }).unwrap(),
774            r#"{"Add":{"a":3,"b":4}}"#
775        );
776        assert_serde_json_serialize_eq!(&Op::Add { a: 3, b: 4 });
777    }
778
779    #[test]
780    fn enum_mixed() {
781        #[derive(Serialize)]
782        enum Animal {
783            Ant,
784            #[serde(rename = "kitty")]
785            Cat,
786            Dog(),
787            Horse {},
788            Zebra {
789                height: u32,
790            },
791        }
792        assert_eq!(to_string(&Animal::Ant).unwrap(), r#""Ant""#);
793        assert_eq!(to_string(&Animal::Cat).unwrap(), r#""kitty""#);
794        assert_eq!(to_string(&Animal::Dog()).unwrap(), r#"{"Dog":[]}"#);
795        assert_eq!(to_string(&Animal::Horse {}).unwrap(), r#"{"Horse":{}}"#);
796        assert_eq!(
797            to_string(&Animal::Zebra { height: 273 }).unwrap(),
798            r#"{"Zebra":{"height":273}}"#
799        );
800    }
801
802    #[test]
803    fn str() {
804        assert_eq!(to_string("hello").unwrap(), r#""hello""#);
805        assert_eq!(to_string("").unwrap(), r#""""#);
806
807        // Characters unescaped if possible
808        assert_eq!(to_string("ä").unwrap(), r#""ä""#);
809        assert_eq!(to_string("৬").unwrap(), r#""৬""#);
810        assert_eq!(to_string("\u{A0}").unwrap(), r#"" ""#); // non-breaking space
811        assert_eq!(to_string("ℝ").unwrap(), r#""ℝ""#); // 3 byte character
812        assert_eq!(to_string("💣").unwrap(), r#""💣""#); // 4 byte character
813
814        // " and \ must be escaped
815        assert_eq!(to_string("foo\"bar").unwrap(), r#""foo\"bar""#);
816        assert_eq!(to_string("foo\\bar").unwrap(), r#""foo\\bar""#);
817
818        // \b, \t, \n, \f, \r must be escaped in their two-character escaping
819        assert_eq!(to_string(" \u{0008} ").unwrap(), r#"" \b ""#);
820        assert_eq!(to_string(" \u{0009} ").unwrap(), r#"" \t ""#);
821        assert_eq!(to_string(" \u{000A} ").unwrap(), r#"" \n ""#);
822        assert_eq!(to_string(" \u{000C} ").unwrap(), r#"" \f ""#);
823        assert_eq!(to_string(" \u{000D} ").unwrap(), r#"" \r ""#);
824
825        // U+0000 through U+001F is escaped using six-character \u00xx uppercase hexadecimal escape sequences
826        assert_eq!(to_string(" \u{0000} ").unwrap(), r#"" \u0000 ""#);
827        assert_eq!(to_string(" \u{0001} ").unwrap(), r#"" \u0001 ""#);
828        assert_eq!(to_string(" \u{0007} ").unwrap(), r#"" \u0007 ""#);
829        assert_eq!(to_string(" \u{000e} ").unwrap(), r#"" \u000E ""#);
830        assert_eq!(to_string(" \u{001D} ").unwrap(), r#"" \u001D ""#);
831        assert_eq!(to_string(" \u{001f} ").unwrap(), r#"" \u001F ""#);
832    }
833
834    #[test]
835    fn collect_str_can_be_used_in_custom_seralize_impl() {
836        struct SpecialType {
837            count: u32,
838            on: bool,
839        }
840
841        impl Serialize for SpecialType {
842            // A custom Serialize implementation for SpecialType. SpecialType is giving us the chance to use
843            // an efficient collect_str implementation that is better than allocating the String and running
844            // serialize_str on it.
845            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
846            where
847                S: Serializer,
848            {
849                serializer.collect_str(&format_args!("{}-{}", self.count, self.on))
850            }
851        }
852
853        let value = SpecialType {
854            count: 123,
855            on: false,
856        };
857        assert_eq!(to_string(&value).unwrap(), r#""123-false""#);
858    }
859
860    #[test]
861    fn newtype() {
862        #[derive(Serialize)]
863        struct Address(String);
864        #[derive(Serialize)]
865        struct CommentId(u32);
866
867        // string
868        assert_eq!(
869            to_string(&Address("home".to_string())).unwrap(),
870            r#""home""#
871        );
872        assert_serde_json_serialize_eq!(&Address("home".to_string()));
873
874        // number
875        assert_eq!(to_string(&CommentId(42)).unwrap(), r#"42"#);
876        assert_serde_json_serialize_eq!(&CommentId(42));
877    }
878
879    #[test]
880    fn struct_bool() {
881        #[derive(Serialize)]
882        struct Led {
883            led: bool,
884        }
885
886        assert_eq!(to_string(&Led { led: true }).unwrap(), r#"{"led":true}"#);
887        assert_serde_json_serialize_eq!(&Led { led: true });
888    }
889
890    #[test]
891    fn struct_i8() {
892        #[derive(Serialize)]
893        struct Temperature {
894            temperature: i8,
895        }
896
897        assert_eq!(
898            to_string(&Temperature { temperature: 127 }).unwrap(),
899            r#"{"temperature":127}"#
900        );
901        assert_eq!(
902            to_string(&Temperature { temperature: 20 }).unwrap(),
903            r#"{"temperature":20}"#
904        );
905        assert_eq!(
906            to_string(&Temperature { temperature: -17 }).unwrap(),
907            r#"{"temperature":-17}"#
908        );
909        assert_eq!(
910            to_string(&Temperature { temperature: -128 }).unwrap(),
911            r#"{"temperature":-128}"#
912        );
913        assert_serde_json_serialize_eq!(&Temperature { temperature: -128 });
914    }
915
916    #[test]
917    fn struct_option() {
918        #[derive(Serialize)]
919        struct Property<'a> {
920            description: Option<&'a str>,
921        }
922
923        assert_eq!(
924            to_string(&Property {
925                description: Some("An ambient temperature sensor"),
926            })
927            .unwrap(),
928            r#"{"description":"An ambient temperature sensor"}"#
929        );
930        assert_serde_json_serialize_eq!(&Property {
931            description: Some("An ambient temperature sensor"),
932        });
933
934        assert_eq!(
935            to_string(&Property { description: None }).unwrap(),
936            r#"{"description":null}"#
937        );
938        assert_serde_json_serialize_eq!(&Property { description: None });
939    }
940
941    #[test]
942    fn struct_u8() {
943        #[derive(Serialize)]
944        struct Temperature {
945            temperature: u8,
946        }
947
948        assert_eq!(
949            to_string(&Temperature { temperature: 20 }).unwrap(),
950            r#"{"temperature":20}"#
951        );
952        assert_serde_json_serialize_eq!(&Temperature { temperature: 20 });
953    }
954
955    #[test]
956    fn struct_() {
957        #[derive(Serialize)]
958        struct Nothing;
959
960        assert_eq!(to_string(&Nothing).unwrap(), r#"null"#);
961        assert_serde_json_serialize_eq!(&Nothing);
962
963        #[derive(Serialize)]
964        struct Empty {}
965
966        assert_eq!(to_string(&Empty {}).unwrap(), r#"{}"#);
967        assert_serde_json_serialize_eq!(&Empty {});
968
969        #[derive(Serialize)]
970        struct Tuple {
971            a: bool,
972            b: bool,
973        }
974
975        assert_eq!(
976            to_string(&Tuple { a: true, b: false }).unwrap(),
977            r#"{"a":true,"b":false}"#
978        );
979        assert_serde_json_serialize_eq!(&Tuple { a: true, b: false });
980    }
981
982    #[test]
983    fn struct_with_flatten() {
984        #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
985        struct Pagination {
986            limit: u64,
987            offset: u64,
988            total: u64,
989        }
990
991        #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
992        struct Users {
993            users: Vec<String>,
994
995            #[serde(flatten)]
996            pagination: Pagination,
997        }
998
999        let users = Users {
1000            users: vec!["joe".into(), "alice".into()],
1001            pagination: Pagination {
1002                offset: 100,
1003                limit: 20,
1004                total: 102,
1005            },
1006        };
1007
1008        assert_eq!(
1009            to_string(&users).unwrap(),
1010            r#"{"users":["joe","alice"],"limit":20,"offset":100,"total":102}"#
1011        );
1012        assert_serde_json_serialize_eq!(&users);
1013    }
1014
1015    #[test]
1016    fn btree_map() {
1017        // empty map
1018        let empty = BTreeMap::<(), ()>::new();
1019        assert_eq!(to_string(&empty).unwrap(), r#"{}"#);
1020        assert_serde_json_serialize_eq!(&empty);
1021
1022        // One element with unit type
1023        let mut map = BTreeMap::<&str, ()>::new();
1024        map.insert("set_element", ());
1025        assert_eq!(to_string(&map).unwrap(), r#"{"set_element":null}"#);
1026        assert_serde_json_serialize_eq!(&map);
1027
1028        let mut two_values = BTreeMap::new();
1029        two_values.insert("my_name", "joseph");
1030        two_values.insert("her_name", "aline");
1031        assert_eq!(
1032            to_string(&two_values).unwrap(),
1033            r#"{"her_name":"aline","my_name":"joseph"}"#
1034        );
1035        assert_serde_json_serialize_eq!(&two_values);
1036
1037        let mut nested_map = BTreeMap::new();
1038        nested_map.insert("two_entries", two_values.clone());
1039
1040        two_values.remove("my_name");
1041        nested_map.insert("one_entry", two_values);
1042        assert_eq!(
1043            to_string(&nested_map).unwrap(),
1044            r#"{"one_entry":{"her_name":"aline"},"two_entries":{"her_name":"aline","my_name":"joseph"}}"#
1045        );
1046        assert_serde_json_serialize_eq!(&nested_map);
1047    }
1048
1049    #[test]
1050    fn hash_map() {
1051        // empty map
1052        let empty = HashMap::<(), ()>::new();
1053        assert_eq!(to_string(&empty).unwrap(), r#"{}"#);
1054        assert_serde_json_serialize_eq!(&empty);
1055
1056        // One element
1057        let mut map = HashMap::new();
1058        map.insert("my_age", 28);
1059        assert_eq!(to_string(&map).unwrap(), r#"{"my_age":28}"#);
1060        assert_serde_json_serialize_eq!(&map);
1061
1062        #[derive(Debug, Serialize, PartialEq, Eq, Hash)]
1063        pub struct NewType(String);
1064
1065        // New type wrappers around String types work as keys
1066        let mut map = HashMap::new();
1067        map.insert(NewType(String::from("my_age")), 44);
1068        assert_eq!(to_string(&map).unwrap(), r#"{"my_age":44}"#);
1069        assert_serde_json_serialize_eq!(&map);
1070
1071        #[derive(Debug, Serialize, PartialEq, Eq, Hash)]
1072        #[serde(rename_all = "lowercase")]
1073        pub enum MyResult {
1074            Err,
1075        }
1076
1077        // Unit variants are also valid keys
1078        let mut map = HashMap::new();
1079        map.insert(MyResult::Err, 404);
1080        assert_eq!(to_string(&map).unwrap(), r#"{"err":404}"#);
1081        assert_serde_json_serialize_eq!(&map);
1082
1083        // HashMap does not have deterministic iteration order (except in the Wasm target).
1084        // So the two element map is serialized as one of two options.
1085        let mut two_values = HashMap::new();
1086        two_values.insert("my_name", "joseph");
1087        two_values.insert("her_name", "aline");
1088        let serialized = to_string(&two_values).unwrap();
1089        assert!(
1090            serialized == r#"{"her_name":"aline","my_name":"joseph"}"#
1091                || serialized == r#"{"my_name":"joseph","her_name":"aline"}"#
1092        );
1093        assert_serde_json_serialize_eq!(&two_values);
1094    }
1095
1096    #[test]
1097    fn number_key() {
1098        // i8 key
1099        let mut map = HashMap::new();
1100        map.insert(10i8, "my_age");
1101        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1102        assert_serde_json_serialize_eq!(&map);
1103
1104        // i16 key
1105        let mut map = HashMap::new();
1106        map.insert(10i16, "my_age");
1107        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1108        assert_serde_json_serialize_eq!(&map);
1109
1110        // i32 key
1111        let mut map = HashMap::new();
1112        map.insert(10i32, "my_age");
1113        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1114        assert_serde_json_serialize_eq!(&map);
1115
1116        // i64 key
1117        let mut map = HashMap::new();
1118        map.insert(10i64, "my_age");
1119        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1120
1121        // i128 key
1122        let mut map = HashMap::new();
1123        map.insert(10i128, "my_age");
1124        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1125        assert_serde_json_serialize_eq!(&map);
1126
1127        // u8 key
1128        let mut map = HashMap::new();
1129        map.insert(10u8, "my_age");
1130        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1131        assert_serde_json_serialize_eq!(&map);
1132
1133        // u16 key
1134        let mut map = HashMap::new();
1135        map.insert(10u16, "my_age");
1136        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1137
1138        // u32 key
1139        let mut map = HashMap::new();
1140        map.insert(10u32, "my_age");
1141        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1142        assert_serde_json_serialize_eq!(&map);
1143
1144        // u64 key
1145        let mut map = HashMap::new();
1146        map.insert(10u64, "my_age");
1147        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1148        assert_serde_json_serialize_eq!(&map);
1149
1150        // u128 key
1151        let mut map = HashMap::new();
1152        map.insert(10u128, "my_age");
1153        assert_eq!(to_string(&map).unwrap(), r#"{"10":"my_age"}"#);
1154        assert_serde_json_serialize_eq!(&map);
1155    }
1156
1157    #[test]
1158    fn invalid_json_key() {
1159        use crate::ser::map::key_must_be_a_string;
1160
1161        #[derive(Debug, Serialize, PartialEq, Eq, Hash)]
1162        #[serde(rename_all = "lowercase")]
1163        pub enum MyResult {
1164            Unit(()),
1165            Ok(Response),
1166        }
1167        #[derive(Debug, Serialize, PartialEq, Eq, Hash)]
1168        pub struct Response {
1169            pub log: Option<String>,
1170            pub count: i64,
1171            pub list: Vec<u32>,
1172        }
1173
1174        // unit enum
1175        let mut map = HashMap::new();
1176        map.insert(MyResult::Unit(()), "my_age");
1177        assert_eq!(
1178            to_string(&map).unwrap_err().to_string(),
1179            key_must_be_a_string().to_string()
1180        );
1181
1182        // struct enum
1183        let mut map = HashMap::new();
1184        map.insert(
1185            MyResult::Ok(Response {
1186                log: None,
1187                count: 1,
1188                list: vec![6],
1189            }),
1190            "my_age",
1191        );
1192        assert_eq!(
1193            to_string(&map).unwrap_err().to_string(),
1194            key_must_be_a_string().to_string()
1195        );
1196
1197        // Struct
1198        let mut map = HashMap::new();
1199        map.insert(
1200            Response {
1201                log: None,
1202                count: 1,
1203                list: vec![6],
1204            },
1205            "my_age",
1206        );
1207        assert_eq!(
1208            to_string(&map).unwrap_err().to_string(),
1209            key_must_be_a_string().to_string()
1210        );
1211    }
1212
1213    #[test]
1214    fn serialize_embedded_enum() {
1215        use serde_derive::Deserialize;
1216
1217        #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
1218        #[serde(rename_all = "lowercase")]
1219        pub enum MyResult {
1220            Unit(()),
1221            Ok(Response),
1222            Err(String),
1223        }
1224
1225        #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
1226        pub struct Response {
1227            pub log: Option<String>,
1228            pub count: i64,
1229            pub list: Vec<u32>,
1230        }
1231
1232        let err_input = MyResult::Err("some error".to_string());
1233        let json = to_string(&err_input).expect("encode err enum");
1234        assert_eq!(json, r#"{"err":"some error"}"#);
1235        let loaded = crate::from_str(&json).expect("re-load err enum");
1236        assert_eq!(err_input, loaded);
1237        assert_serde_json_serialize_eq!(&err_input);
1238
1239        let unit = MyResult::Unit(());
1240        let json = to_string(&unit).expect("encode unit enum");
1241        assert_eq!(json, r#"{"unit":null}"#);
1242        let loaded = crate::from_str(&json).expect("re-load unit enum");
1243        assert_eq!(unit, loaded);
1244        assert_serde_json_serialize_eq!(&unit);
1245
1246        let empty_list = MyResult::Ok(Response {
1247            log: Some("log message".to_string()),
1248            count: 137,
1249            list: Vec::new(),
1250        });
1251        let json = to_string(&empty_list).expect("encode ok enum");
1252        assert_eq!(
1253            json,
1254            r#"{"ok":{"log":"log message","count":137,"list":[]}}"#
1255        );
1256        let loaded = crate::from_str(&json).expect("re-load ok enum");
1257        assert_eq!(empty_list, loaded);
1258        assert_serde_json_serialize_eq!(&empty_list);
1259
1260        let full_list = MyResult::Ok(Response {
1261            log: None,
1262            count: 137,
1263            list: vec![18u32, 34, 12],
1264        });
1265        let json = to_string(&full_list).expect("encode ok enum");
1266        assert_eq!(json, r#"{"ok":{"log":null,"count":137,"list":[18,34,12]}}"#);
1267        let loaded = crate::from_str(&json).expect("re-load ok enum");
1268        assert_eq!(full_list, loaded);
1269        assert_serde_json_serialize_eq!(&full_list);
1270    }
1271}