serde_json_core/ser/
mod.rs

1//! Serialize a Rust data structure into JSON data
2
3use core::mem::MaybeUninit;
4use core::{fmt, str};
5
6use serde::ser;
7use serde::ser::SerializeStruct as _;
8use serde::Serialize;
9
10#[cfg(feature = "heapless")]
11use heapless::{String, Vec};
12
13use self::map::SerializeMap;
14use self::seq::SerializeSeq;
15use self::struct_::{SerializeStruct, SerializeStructVariant};
16
17mod map;
18mod seq;
19mod struct_;
20
21/// Serialization result
22pub type Result<T> = ::core::result::Result<T, Error>;
23
24/// This type represents all possible errors that can occur when serializing JSON data
25#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
26#[cfg_attr(feature = "defmt", derive(defmt::Format))]
27#[non_exhaustive]
28pub enum Error {
29    /// Buffer is full
30    BufferFull,
31}
32
33impl From<()> for Error {
34    fn from(_: ()) -> Error {
35        Error::BufferFull
36    }
37}
38
39impl From<u8> for Error {
40    fn from(_: u8) -> Error {
41        Error::BufferFull
42    }
43}
44
45impl serde::ser::StdError for Error {}
46
47impl fmt::Display for Error {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        write!(f, "Buffer is full")
50    }
51}
52
53/// A structure that serializes Rust values as JSON into a buffer.
54pub struct Serializer<'a> {
55    buf: &'a mut [u8],
56    current_length: usize,
57}
58
59impl<'a> Serializer<'a> {
60    /// Create a new `Serializer`
61    pub fn new(buf: &'a mut [u8]) -> Self {
62        Serializer {
63            buf,
64            current_length: 0,
65        }
66    }
67
68    /// Return the current amount of serialized data in the buffer
69    pub fn end(&self) -> usize {
70        self.current_length
71    }
72
73    fn push(&mut self, c: u8) -> Result<()> {
74        if self.current_length < self.buf.len() {
75            unsafe { self.push_unchecked(c) };
76            Ok(())
77        } else {
78            Err(Error::BufferFull)
79        }
80    }
81
82    unsafe fn push_unchecked(&mut self, c: u8) {
83        self.buf[self.current_length] = c;
84        self.current_length += 1;
85    }
86
87    fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> {
88        if self.current_length + other.len() > self.buf.len() {
89            // won't fit in the buf; don't modify anything and return an error
90            Err(Error::BufferFull)
91        } else {
92            for c in other {
93                unsafe { self.push_unchecked(*c) };
94            }
95            Ok(())
96        }
97    }
98
99    fn push_char(&mut self, c: char) -> Result<()> {
100        // Do escaping according to "6. MUST represent all strings (including object member names) in
101        // their minimal-length UTF-8 encoding": https://gibson042.github.io/canonicaljson-spec/
102        //
103        // We don't need to escape lone surrogates because surrogate pairs do not exist in valid UTF-8,
104        // even if they can exist in JSON or JavaScript strings (UCS-2 based). As a result, lone surrogates
105        // cannot exist in a Rust String. If they do, the bug is in the String constructor.
106        // An excellent explanation is available at https://www.youtube.com/watch?v=HhIEDWmQS3w
107
108        // Temporary storage for encoded a single char.
109        // A char is up to 4 bytes long wehn encoded to UTF-8.
110        let mut encoding_tmp = [0u8; 4];
111
112        match c {
113            '\\' => {
114                self.push(b'\\')?;
115                self.push(b'\\')?;
116            }
117            '"' => {
118                self.push(b'\\')?;
119                self.push(b'"')?;
120            }
121            '\u{0008}' => {
122                self.push(b'\\')?;
123                self.push(b'b')?;
124            }
125            '\u{0009}' => {
126                self.push(b'\\')?;
127                self.push(b't')?;
128            }
129            '\u{000A}' => {
130                self.push(b'\\')?;
131                self.push(b'n')?;
132            }
133            '\u{000C}' => {
134                self.push(b'\\')?;
135                self.push(b'f')?;
136            }
137            '\u{000D}' => {
138                self.push(b'\\')?;
139                self.push(b'r')?;
140            }
141            '\u{0000}'..='\u{001F}' => {
142                self.push(b'\\')?;
143                self.push(b'u')?;
144                self.push(b'0')?;
145                self.push(b'0')?;
146                let (hex1, hex2) = hex(c as u8);
147                self.push(hex1)?;
148                self.push(hex2)?;
149            }
150            _ => {
151                let encoded = c.encode_utf8(&mut encoding_tmp as &mut [u8]);
152                self.extend_from_slice(encoded.as_bytes())?;
153            }
154        }
155
156        Ok(())
157    }
158}
159
160// NOTE(serialize_*signed) This is basically the numtoa implementation minus the lookup tables,
161// which take 200+ bytes of ROM / Flash
162macro_rules! serialize_unsigned {
163    ($self:ident, $N:expr, $v:expr) => {{
164        let mut buf: [MaybeUninit<u8>; $N] = [MaybeUninit::uninit(); $N];
165
166        let mut v = $v;
167        let mut i = $N - 1;
168        loop {
169            buf[i].write((v % 10) as u8 + b'0');
170            v /= 10;
171
172            if v == 0 {
173                break;
174            } else {
175                i -= 1;
176            }
177        }
178
179        // Note(feature): maybe_uninit_slice
180        let buf = unsafe { &*(&buf[i..] as *const _ as *const [u8]) };
181
182        $self.extend_from_slice(buf)
183    }};
184}
185
186macro_rules! serialize_signed {
187    ($self:ident, $N:expr, $v:expr, $ixx:ident, $uxx:ident) => {{
188        let v = $v;
189        let (signed, mut v) = if v == $ixx::MIN {
190            (true, $ixx::MAX as $uxx + 1)
191        } else if v < 0 {
192            (true, -v as $uxx)
193        } else {
194            (false, v as $uxx)
195        };
196
197        let mut buf: [MaybeUninit<u8>; $N] = [MaybeUninit::uninit(); $N];
198        let mut i = $N - 1;
199        loop {
200            buf[i].write((v % 10) as u8 + b'0');
201            v /= 10;
202
203            i -= 1;
204
205            if v == 0 {
206                break;
207            }
208        }
209
210        if signed {
211            buf[i].write(b'-');
212        } else {
213            i += 1;
214        }
215
216        // Note(feature): maybe_uninit_slice
217        let buf = unsafe { &*(&buf[i..] as *const _ as *const [u8]) };
218
219        $self.extend_from_slice(buf)
220    }};
221}
222
223macro_rules! serialize_ryu {
224    ($self:ident, $v:expr) => {{
225        let mut buffer = ryu::Buffer::new();
226        let printed = buffer.format($v);
227        $self.extend_from_slice(printed.as_bytes())
228    }};
229}
230
231/// Upper-case hex for value in 0..16, encoded as ASCII bytes
232fn hex_4bit(c: u8) -> u8 {
233    if c <= 9 {
234        0x30 + c
235    } else {
236        0x41 + (c - 10)
237    }
238}
239
240/// Upper-case hex for value in 0..256, encoded as ASCII bytes
241fn hex(c: u8) -> (u8, u8) {
242    (hex_4bit(c >> 4), hex_4bit(c & 0x0F))
243}
244
245impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> {
246    type Ok = ();
247    type Error = Error;
248    type SerializeSeq = SerializeSeq<'a, 'b>;
249    type SerializeTuple = SerializeSeq<'a, 'b>;
250    type SerializeTupleStruct = SerializeSeq<'a, 'b>;
251    type SerializeTupleVariant = Unreachable;
252    type SerializeMap = SerializeMap<'a, 'b>;
253    type SerializeStruct = SerializeStruct<'a, 'b>;
254    type SerializeStructVariant = SerializeStructVariant<'a, 'b>;
255
256    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
257        if v {
258            self.extend_from_slice(b"true")
259        } else {
260            self.extend_from_slice(b"false")
261        }
262    }
263
264    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
265        // "-128"
266        serialize_signed!(self, 4, v, i8, u8)
267    }
268
269    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
270        // "-32768"
271        serialize_signed!(self, 6, v, i16, u16)
272    }
273
274    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
275        // "-2147483648"
276        serialize_signed!(self, 11, v, i32, u32)
277    }
278
279    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
280        // "-9223372036854775808"
281        serialize_signed!(self, 20, v, i64, u64)
282    }
283
284    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
285        // "255"
286        serialize_unsigned!(self, 3, v)
287    }
288
289    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
290        // "65535"
291        serialize_unsigned!(self, 5, v)
292    }
293
294    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
295        // "4294967295"
296        serialize_unsigned!(self, 10, v)
297    }
298
299    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
300        // "18446744073709551615"
301        serialize_unsigned!(self, 20, v)
302    }
303
304    fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
305        if v.is_finite() {
306            serialize_ryu!(self, v)
307        } else {
308            self.serialize_none()
309        }
310    }
311
312    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
313        if v.is_finite() {
314            serialize_ryu!(self, v)
315        } else {
316            self.serialize_none()
317        }
318    }
319
320    fn serialize_char(self, _v: char) -> Result<Self::Ok> {
321        unreachable!()
322    }
323
324    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
325        self.push(b'"')?;
326
327        for c in v.chars() {
328            self.push_char(c)?;
329        }
330
331        self.push(b'"')
332    }
333
334    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
335        self.extend_from_slice(v)
336    }
337
338    fn serialize_none(self) -> Result<Self::Ok> {
339        self.extend_from_slice(b"null")
340    }
341
342    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
343    where
344        T: ser::Serialize + ?Sized,
345    {
346        value.serialize(self)
347    }
348
349    fn serialize_unit(self) -> Result<Self::Ok> {
350        self.serialize_none()
351    }
352
353    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
354        self.serialize_unit()
355    }
356
357    fn serialize_unit_variant(
358        self,
359        _name: &'static str,
360        _variant_index: u32,
361        variant: &'static str,
362    ) -> Result<Self::Ok> {
363        self.serialize_str(variant)
364    }
365
366    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Self::Ok>
367    where
368        T: ser::Serialize + ?Sized,
369    {
370        // If the newtype struct is an `EscapedStr`...
371        if name == crate::str::EscapedStr::NAME {
372            // serialize it as an already escaped string.
373
374            struct EscapedStringSerializer<'a, 'b>(&'a mut Serializer<'b>);
375
376            impl<'a, 'b: 'a> serde::Serializer for EscapedStringSerializer<'a, 'b> {
377                type Ok = ();
378                type Error = Error;
379
380                type SerializeSeq = serde::ser::Impossible<(), Error>;
381                type SerializeTuple = serde::ser::Impossible<(), Error>;
382                type SerializeTupleStruct = serde::ser::Impossible<(), Error>;
383                type SerializeTupleVariant = serde::ser::Impossible<(), Error>;
384                type SerializeMap = serde::ser::Impossible<(), Error>;
385                type SerializeStruct = serde::ser::Impossible<(), Error>;
386                type SerializeStructVariant = serde::ser::Impossible<(), Error>;
387
388                fn serialize_bool(self, _v: bool) -> Result<Self::Ok> {
389                    unreachable!()
390                }
391
392                fn serialize_i8(self, _v: i8) -> Result<Self::Ok> {
393                    unreachable!()
394                }
395
396                fn serialize_i16(self, _v: i16) -> Result<Self::Ok> {
397                    unreachable!()
398                }
399
400                fn serialize_i32(self, _v: i32) -> Result<Self::Ok> {
401                    unreachable!()
402                }
403
404                fn serialize_i64(self, _v: i64) -> Result<Self::Ok> {
405                    unreachable!()
406                }
407
408                fn serialize_u8(self, _v: u8) -> Result<Self::Ok> {
409                    unreachable!()
410                }
411
412                fn serialize_u16(self, _v: u16) -> Result<Self::Ok> {
413                    unreachable!()
414                }
415
416                fn serialize_u32(self, _v: u32) -> Result<Self::Ok> {
417                    unreachable!()
418                }
419
420                fn serialize_u64(self, _v: u64) -> Result<Self::Ok> {
421                    unreachable!()
422                }
423
424                fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
425                    unreachable!()
426                }
427
428                fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
429                    unreachable!()
430                }
431
432                fn serialize_char(self, _v: char) -> Result<Self::Ok> {
433                    unreachable!()
434                }
435
436                fn serialize_str(self, v: &str) -> Result<Self::Ok> {
437                    v.bytes().try_for_each(|c| self.0.push(c))
438                }
439
440                fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
441                    unreachable!()
442                }
443
444                fn serialize_none(self) -> Result<Self::Ok> {
445                    unreachable!()
446                }
447
448                fn serialize_some<T: Serialize + ?Sized>(self, _value: &T) -> Result<Self::Ok> {
449                    unreachable!()
450                }
451
452                fn serialize_unit(self) -> Result<Self::Ok> {
453                    unreachable!()
454                }
455
456                fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
457                    unreachable!()
458                }
459
460                fn serialize_unit_variant(
461                    self,
462                    _name: &'static str,
463                    _variant_index: u32,
464                    _variant: &'static str,
465                ) -> Result<Self::Ok> {
466                    unreachable!()
467                }
468
469                fn serialize_newtype_struct<T: Serialize + ?Sized>(
470                    self,
471                    _name: &'static str,
472                    _value: &T,
473                ) -> Result<Self::Ok> {
474                    unreachable!()
475                }
476
477                fn serialize_newtype_variant<T: Serialize + ?Sized>(
478                    self,
479                    _name: &'static str,
480                    _variant_index: u32,
481                    _variant: &'static str,
482                    _value: &T,
483                ) -> Result<Self::Ok> {
484                    unreachable!()
485                }
486
487                fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
488                    unreachable!()
489                }
490
491                fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
492                    unreachable!()
493                }
494
495                fn serialize_tuple_struct(
496                    self,
497                    _name: &'static str,
498                    _len: usize,
499                ) -> Result<Self::SerializeTupleStruct> {
500                    unreachable!()
501                }
502
503                fn serialize_tuple_variant(
504                    self,
505                    _name: &'static str,
506                    _variant_index: u32,
507                    _variant: &'static str,
508                    _len: usize,
509                ) -> Result<Self::SerializeTupleVariant> {
510                    unreachable!()
511                }
512
513                fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
514                    unreachable!()
515                }
516
517                fn serialize_struct(
518                    self,
519                    _name: &'static str,
520                    _len: usize,
521                ) -> Result<Self::SerializeStruct> {
522                    unreachable!()
523                }
524
525                fn serialize_struct_variant(
526                    self,
527                    _name: &'static str,
528                    _variant_index: u32,
529                    _variant: &'static str,
530                    _len: usize,
531                ) -> Result<Self::SerializeStructVariant> {
532                    unreachable!()
533                }
534
535                fn collect_str<T: fmt::Display + ?Sized>(self, _value: &T) -> Result<Self::Ok> {
536                    unreachable!()
537                }
538            }
539
540            self.push(b'"')?;
541
542            value.serialize(EscapedStringSerializer(self))?;
543
544            self.push(b'"')?;
545
546            Ok(())
547        } else {
548            value.serialize(self)
549        }
550    }
551
552    fn serialize_newtype_variant<T>(
553        self,
554        _name: &'static str,
555        _variant_index: u32,
556        variant: &'static str,
557        value: &T,
558    ) -> Result<Self::Ok>
559    where
560        T: ser::Serialize + ?Sized,
561    {
562        self.push(b'{')?;
563        let mut s = SerializeStruct::new(self);
564        s.serialize_field(variant, value)?;
565        s.end()?;
566        Ok(())
567    }
568
569    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
570        self.push(b'[')?;
571
572        Ok(SerializeSeq::new(self))
573    }
574
575    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
576        self.serialize_seq(Some(_len))
577    }
578
579    fn serialize_tuple_struct(
580        self,
581        _name: &'static str,
582        len: usize,
583    ) -> Result<Self::SerializeTupleStruct> {
584        self.serialize_seq(Some(len))
585    }
586
587    fn serialize_tuple_variant(
588        self,
589        _name: &'static str,
590        _variant_index: u32,
591        _variant: &'static str,
592        _len: usize,
593    ) -> Result<Self::SerializeTupleVariant> {
594        unreachable!()
595    }
596
597    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
598        self.push(b'{')?;
599
600        Ok(SerializeMap::new(self))
601    }
602
603    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
604        self.push(b'{')?;
605
606        Ok(SerializeStruct::new(self))
607    }
608
609    fn serialize_struct_variant(
610        self,
611        _name: &'static str,
612        _variant_index: u32,
613        variant: &'static str,
614        _len: usize,
615    ) -> Result<Self::SerializeStructVariant> {
616        self.extend_from_slice(b"{\"")?;
617        self.extend_from_slice(variant.as_bytes())?;
618        self.extend_from_slice(b"\":{")?;
619
620        Ok(SerializeStructVariant::new(self))
621    }
622
623    fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
624    where
625        T: fmt::Display + ?Sized,
626    {
627        self.push(b'"')?;
628
629        let mut col = StringCollector::new(self);
630        fmt::write(&mut col, format_args!("{}", value)).or(Err(Error::BufferFull))?;
631
632        self.push(b'"')
633    }
634}
635
636struct StringCollector<'a, 'b> {
637    ser: &'a mut Serializer<'b>,
638}
639
640impl<'a, 'b> StringCollector<'a, 'b> {
641    pub fn new(ser: &'a mut Serializer<'b>) -> Self {
642        Self { ser }
643    }
644
645    fn do_write_str(&mut self, s: &str) -> Result<()> {
646        for c in s.chars() {
647            self.ser.push_char(c)?;
648        }
649
650        Ok(())
651    }
652}
653
654impl<'a, 'b> fmt::Write for StringCollector<'a, 'b> {
655    fn write_str(&mut self, s: &str) -> fmt::Result {
656        self.do_write_str(s).or(Err(fmt::Error))
657    }
658}
659
660/// Serializes the given data structure as a string of JSON text
661#[cfg(feature = "heapless")]
662pub fn to_string<T, const N: usize>(value: &T) -> Result<String<N>>
663where
664    T: ser::Serialize + ?Sized,
665{
666    Ok(unsafe { String::from_utf8_unchecked(to_vec::<T, N>(value)?) })
667}
668
669/// Serializes the given data structure as a JSON byte vector
670#[cfg(feature = "heapless")]
671pub fn to_vec<T, const N: usize>(value: &T) -> Result<Vec<u8, N>>
672where
673    T: ser::Serialize + ?Sized,
674{
675    let mut buf = Vec::<u8, N>::new();
676    buf.resize_default(N)?;
677    let len = to_slice(value, &mut buf)?;
678    buf.truncate(len);
679    Ok(buf)
680}
681
682/// Serializes the given data structure as a JSON byte vector into the provided buffer
683pub fn to_slice<T>(value: &T, buf: &mut [u8]) -> Result<usize>
684where
685    T: ser::Serialize + ?Sized,
686{
687    let mut ser = Serializer::new(buf);
688    value.serialize(&mut ser)?;
689    Ok(ser.current_length)
690}
691
692impl ser::Error for Error {
693    fn custom<T>(_msg: T) -> Self
694    where
695        T: fmt::Display,
696    {
697        unreachable!()
698    }
699}
700
701/// An unreachable type to fill the SerializeTupleVariant type
702pub enum Unreachable {}
703
704impl ser::SerializeTupleVariant for Unreachable {
705    type Ok = ();
706    type Error = Error;
707
708    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
709        unreachable!()
710    }
711
712    fn end(self) -> Result<Self::Ok> {
713        unreachable!()
714    }
715}
716
717#[cfg(test)]
718mod tests {
719    use serde_derive::Serialize;
720
721    const N: usize = 128;
722
723    #[test]
724    fn array() {
725        let buf = &mut [0u8; 128];
726        let len = crate::to_slice(&[0, 1, 2], buf).unwrap();
727        assert_eq!(len, 7);
728        assert_eq!(&buf[..len], b"[0,1,2]");
729        assert_eq!(&*crate::to_string::<_, N>(&[0, 1, 2]).unwrap(), "[0,1,2]");
730    }
731
732    #[test]
733    fn bool() {
734        let buf = &mut [0u8; 128];
735        let len = crate::to_slice(&true, buf).unwrap();
736        assert_eq!(len, 4);
737        assert_eq!(&buf[..len], b"true");
738
739        assert_eq!(&*crate::to_string::<_, N>(&true).unwrap(), "true");
740    }
741
742    #[test]
743    fn enum_() {
744        #[derive(Serialize)]
745        enum Type {
746            #[serde(rename = "boolean")]
747            Boolean,
748            #[serde(rename = "number")]
749            Number,
750        }
751
752        assert_eq!(
753            &*crate::to_string::<_, N>(&Type::Boolean).unwrap(),
754            r#""boolean""#
755        );
756
757        assert_eq!(
758            &*crate::to_string::<_, N>(&Type::Number).unwrap(),
759            r#""number""#
760        );
761    }
762
763    #[test]
764    fn str() {
765        assert_eq!(&*crate::to_string::<_, N>("hello").unwrap(), r#""hello""#);
766        assert_eq!(&*crate::to_string::<_, N>("").unwrap(), r#""""#);
767
768        // Characters unescaped if possible
769        assert_eq!(&*crate::to_string::<_, N>("ä").unwrap(), r#""ä""#);
770        assert_eq!(&*crate::to_string::<_, N>("৬").unwrap(), r#""৬""#);
771        // assert_eq!(&*crate::to_string::<_, N>("\u{A0}").unwrap(), r#"" ""#); // non-breaking space
772        assert_eq!(&*crate::to_string::<_, N>("ℝ").unwrap(), r#""ℝ""#); // 3 byte character
773        assert_eq!(&*crate::to_string::<_, N>("💣").unwrap(), r#""💣""#); // 4 byte character
774
775        // " and \ must be escaped
776        assert_eq!(
777            &*crate::to_string::<_, N>("foo\"bar").unwrap(),
778            r#""foo\"bar""#
779        );
780        assert_eq!(
781            &*crate::to_string::<_, N>("foo\\bar").unwrap(),
782            r#""foo\\bar""#
783        );
784
785        // \b, \t, \n, \f, \r must be escaped in their two-character escaping
786        assert_eq!(
787            &*crate::to_string::<_, N>(" \u{0008} ").unwrap(),
788            r#"" \b ""#
789        );
790        assert_eq!(
791            &*crate::to_string::<_, N>(" \u{0009} ").unwrap(),
792            r#"" \t ""#
793        );
794        assert_eq!(
795            &*crate::to_string::<_, N>(" \u{000A} ").unwrap(),
796            r#"" \n ""#
797        );
798        assert_eq!(
799            &*crate::to_string::<_, N>(" \u{000C} ").unwrap(),
800            r#"" \f ""#
801        );
802        assert_eq!(
803            &*crate::to_string::<_, N>(" \u{000D} ").unwrap(),
804            r#"" \r ""#
805        );
806
807        // U+0000 through U+001F is escaped using six-character \u00xx uppercase hexadecimal escape sequences
808        assert_eq!(
809            &*crate::to_string::<_, N>(" \u{0000} ").unwrap(),
810            r#"" \u0000 ""#
811        );
812        assert_eq!(
813            &*crate::to_string::<_, N>(" \u{0001} ").unwrap(),
814            r#"" \u0001 ""#
815        );
816        assert_eq!(
817            &*crate::to_string::<_, N>(" \u{0007} ").unwrap(),
818            r#"" \u0007 ""#
819        );
820        assert_eq!(
821            &*crate::to_string::<_, N>(" \u{000e} ").unwrap(),
822            r#"" \u000E ""#
823        );
824        assert_eq!(
825            &*crate::to_string::<_, N>(" \u{001D} ").unwrap(),
826            r#"" \u001D ""#
827        );
828        assert_eq!(
829            crate::to_string::<_, N>(" \u{001f} ").unwrap(),
830            r#"" \u001F ""#
831        );
832    }
833
834    #[test]
835    fn escaped_str() {
836        assert_eq!(
837            crate::to_string::<_, N>(&crate::str::EscapedStr(r#"Hello\\nWorld"#)).unwrap(),
838            r#""Hello\\nWorld""#
839        );
840    }
841
842    #[test]
843    fn struct_bool() {
844        #[derive(Serialize)]
845        struct Led {
846            led: bool,
847        }
848
849        assert_eq!(
850            &*crate::to_string::<_, N>(&Led { led: true }).unwrap(),
851            r#"{"led":true}"#
852        );
853    }
854
855    #[test]
856    fn struct_i8() {
857        #[derive(Serialize)]
858        struct Temperature {
859            temperature: i8,
860        }
861
862        assert_eq!(
863            &*crate::to_string::<_, N>(&Temperature { temperature: 127 }).unwrap(),
864            r#"{"temperature":127}"#
865        );
866
867        assert_eq!(
868            &*crate::to_string::<_, N>(&Temperature { temperature: 20 }).unwrap(),
869            r#"{"temperature":20}"#
870        );
871
872        assert_eq!(
873            &*crate::to_string::<_, N>(&Temperature { temperature: -17 }).unwrap(),
874            r#"{"temperature":-17}"#
875        );
876
877        assert_eq!(
878            &*crate::to_string::<_, N>(&Temperature { temperature: -128 }).unwrap(),
879            r#"{"temperature":-128}"#
880        );
881    }
882
883    #[test]
884    fn struct_f32() {
885        #[derive(Serialize)]
886        struct Temperature {
887            temperature: f32,
888        }
889
890        assert_eq!(
891            &*crate::to_string::<_, N>(&Temperature { temperature: -20. }).unwrap(),
892            r#"{"temperature":-20.0}"#
893        );
894
895        assert_eq!(
896            &*crate::to_string::<_, N>(&Temperature {
897                temperature: -20345.
898            })
899            .unwrap(),
900            r#"{"temperature":-20345.0}"#
901        );
902
903        assert_eq!(
904            &*crate::to_string::<_, N>(&Temperature {
905                temperature: -2.345_678_8e-23
906            })
907            .unwrap(),
908            r#"{"temperature":-2.3456788e-23}"#
909        );
910
911        assert_eq!(
912            &*crate::to_string::<_, N>(&Temperature {
913                temperature: f32::NAN
914            })
915            .unwrap(),
916            r#"{"temperature":null}"#
917        );
918
919        assert_eq!(
920            &*crate::to_string::<_, N>(&Temperature {
921                temperature: f32::NEG_INFINITY
922            })
923            .unwrap(),
924            r#"{"temperature":null}"#
925        );
926    }
927
928    #[test]
929    fn struct_option() {
930        #[derive(Serialize)]
931        struct Property<'a> {
932            description: Option<&'a str>,
933        }
934
935        assert_eq!(
936            crate::to_string::<_, N>(&Property {
937                description: Some("An ambient temperature sensor"),
938            })
939            .unwrap(),
940            r#"{"description":"An ambient temperature sensor"}"#
941        );
942
943        // XXX Ideally this should produce "{}"
944        assert_eq!(
945            crate::to_string::<_, N>(&Property { description: None }).unwrap(),
946            r#"{"description":null}"#
947        );
948    }
949
950    #[test]
951    fn struct_u8() {
952        #[derive(Serialize)]
953        struct Temperature {
954            temperature: u8,
955        }
956
957        assert_eq!(
958            &*crate::to_string::<_, N>(&Temperature { temperature: 20 }).unwrap(),
959            r#"{"temperature":20}"#
960        );
961    }
962
963    #[test]
964    fn struct_() {
965        #[derive(Serialize)]
966        struct Empty {}
967
968        assert_eq!(&*crate::to_string::<_, N>(&Empty {}).unwrap(), r#"{}"#);
969
970        #[derive(Serialize)]
971        struct Tuple {
972            a: bool,
973            b: bool,
974        }
975
976        assert_eq!(
977            &*crate::to_string::<_, N>(&Tuple { a: true, b: false }).unwrap(),
978            r#"{"a":true,"b":false}"#
979        );
980    }
981
982    #[test]
983    fn test_unit() {
984        let a = ();
985        assert_eq!(&*crate::to_string::<_, N>(&a).unwrap(), r#"null"#);
986    }
987
988    #[test]
989    fn test_newtype_struct() {
990        #[derive(Serialize)]
991        struct A(pub u32);
992        let a = A(54);
993        assert_eq!(&*crate::to_string::<_, N>(&a).unwrap(), r#"54"#);
994    }
995
996    #[test]
997    fn test_newtype_variant() {
998        #[derive(Serialize)]
999        enum A {
1000            A(u32),
1001        }
1002        let a = A::A(54);
1003
1004        assert_eq!(&*crate::to_string::<_, N>(&a).unwrap(), r#"{"A":54}"#);
1005    }
1006
1007    #[test]
1008    fn test_struct_variant() {
1009        #[derive(Serialize)]
1010        enum A {
1011            A { x: u32, y: u16 },
1012        }
1013        let a = A::A { x: 54, y: 720 };
1014
1015        assert_eq!(
1016            &*crate::to_string::<_, N>(&a).unwrap(),
1017            r#"{"A":{"x":54,"y":720}}"#
1018        );
1019    }
1020
1021    #[test]
1022    fn test_tuple_struct() {
1023        #[derive(Serialize)]
1024        struct A<'a>(u32, Option<&'a str>, u16, bool);
1025
1026        let a = A(42, Some("A string"), 720, false);
1027
1028        assert_eq!(
1029            &*crate::to_string::<_, N>(&a).unwrap(),
1030            r#"[42,"A string",720,false]"#
1031        );
1032    }
1033
1034    #[test]
1035    fn test_tuple_struct_roundtrip() {
1036        use serde_derive::Deserialize;
1037
1038        #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
1039        struct A<'a>(u32, Option<&'a str>, u16, bool);
1040
1041        let a1 = A(42, Some("A string"), 720, false);
1042        let serialized = crate::to_string::<_, N>(&a1).unwrap();
1043        let (a2, _size): (A<'_>, usize) = crate::from_str(&serialized).unwrap();
1044        assert_eq!(a1, a2);
1045    }
1046
1047    #[test]
1048    fn test_serialize_bytes() {
1049        use core::fmt::Write;
1050        use heapless::String;
1051
1052        pub struct SimpleDecimal(f32);
1053
1054        impl serde::Serialize for SimpleDecimal {
1055            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1056            where
1057                S: serde::Serializer,
1058            {
1059                let mut aux: String<{ N }> = String::new();
1060                write!(aux, "{:.2}", self.0).unwrap();
1061                serializer.serialize_bytes(aux.as_bytes())
1062            }
1063        }
1064
1065        let sd1 = SimpleDecimal(1.55555);
1066        assert_eq!(&*crate::to_string::<_, N>(&sd1).unwrap(), r#"1.56"#);
1067
1068        let sd2 = SimpleDecimal(0.000);
1069        assert_eq!(&*crate::to_string::<_, N>(&sd2).unwrap(), r#"0.00"#);
1070
1071        let sd3 = SimpleDecimal(22_222.777);
1072        assert_eq!(&*crate::to_string::<_, N>(&sd3).unwrap(), r#"22222.78"#);
1073    }
1074}