Skip to main content

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