pink_json/ser/
mod.rs

1//! Serialize a Rust data structure into JSON data
2use alloc::string::String;
3use alloc::vec::Vec;
4use core::{fmt, str};
5
6use serde::ser;
7use serde::ser::SerializeStruct as _;
8
9use self::map::SerializeMap;
10use self::seq::SerializeSeq;
11use self::struct_::{SerializeStruct, SerializeStructVariant};
12
13mod map;
14mod seq;
15mod struct_;
16
17/// Serialization result
18pub type Result<T> = ::core::result::Result<T, Error>;
19
20/// This type represents all possible errors that can occur when serializing JSON data
21#[derive(Debug)]
22#[non_exhaustive]
23pub enum Error {
24    /// Buffer is full
25    BufferFull,
26    /// The serializing value type are not supported
27    InvalidValue,
28}
29
30impl From<()> for Error {
31    fn from(_: ()) -> Error {
32        Error::BufferFull
33    }
34}
35
36impl From<u8> for Error {
37    fn from(_: u8) -> Error {
38        Error::BufferFull
39    }
40}
41
42#[cfg(feature = "std")]
43impl ::std::error::Error for Error {
44    fn description(&self) -> &str {
45        ""
46    }
47}
48
49impl fmt::Display for Error {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "Buffer is full")
52    }
53}
54
55pub(crate) struct Serializer {
56    buf: Vec<u8>,
57}
58
59impl Serializer {
60    fn new() -> Self {
61        Serializer { buf: Vec::new() }
62    }
63
64    fn push(&mut self, c: u8) -> Result<()> {
65        self.buf.push(c);
66        Ok(())
67    }
68
69    fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> {
70        self.buf.extend_from_slice(other);
71        Ok(())
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: [u8; $N] = unsafe { super::uninitialized() };
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.extend_from_slice(&buf[i..])
95    }};
96}
97
98macro_rules! serialize_signed {
99    ($self:ident, $N:expr, $v:expr, $ixx:ident, $uxx:ident) => {{
100        let v = $v;
101        let (signed, mut v) = if v == $ixx::min_value() {
102            (true, $ixx::max_value() as $uxx + 1)
103        } else if v < 0 {
104            (true, -v as $uxx)
105        } else {
106            (false, v as $uxx)
107        };
108
109        let mut buf: [u8; $N] = unsafe { super::uninitialized() };
110        let mut i = $N - 1;
111        loop {
112            buf[i] = (v % 10) as u8 + b'0';
113            v /= 10;
114
115            i -= 1;
116
117            if v == 0 {
118                break;
119            }
120        }
121
122        if signed {
123            buf[i] = b'-';
124        } else {
125            i += 1;
126        }
127        $self.extend_from_slice(&buf[i..])
128    }};
129}
130
131/// Upper-case hex for value in 0..16, encoded as ASCII bytes
132fn hex_4bit(c: u8) -> u8 {
133    if c <= 9 {
134        0x30 + c
135    } else {
136        0x41 + (c - 10)
137    }
138}
139
140/// Upper-case hex for value in 0..256, encoded as ASCII bytes
141fn hex(c: u8) -> (u8, u8) {
142    (hex_4bit(c >> 4), hex_4bit(c & 0x0F))
143}
144
145impl<'a> ser::Serializer for &'a mut Serializer {
146    type Ok = ();
147    type Error = Error;
148    type SerializeSeq = SerializeSeq<'a>;
149    type SerializeTuple = SerializeSeq<'a>;
150    type SerializeTupleStruct = Unreachable;
151    type SerializeTupleVariant = Unreachable;
152    type SerializeMap = SerializeMap<'a>;
153    type SerializeStruct = SerializeStruct<'a>;
154    type SerializeStructVariant = SerializeStructVariant<'a>;
155
156    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
157        if v {
158            self.extend_from_slice(b"true")
159        } else {
160            self.extend_from_slice(b"false")
161        }
162    }
163
164    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
165        // "-128"
166        serialize_signed!(self, 4, v, i8, u8)
167    }
168
169    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
170        // "-32768"
171        serialize_signed!(self, 6, v, i16, u16)
172    }
173
174    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
175        // "-2147483648"
176        serialize_signed!(self, 11, v, i32, u32)
177    }
178
179    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
180        // "-9223372036854775808"
181        serialize_signed!(self, 20, v, i64, u64)
182    }
183
184    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
185        // "255"
186        serialize_unsigned!(self, 3, v)
187    }
188
189    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
190        // "65535"
191        serialize_unsigned!(self, 5, v)
192    }
193
194    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
195        // "4294967295"
196        serialize_unsigned!(self, 10, v)
197    }
198
199    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
200        // "18446744073709551615"
201        serialize_unsigned!(self, 20, v)
202    }
203
204    fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
205        Err(Error::InvalidValue)
206    }
207
208    fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
209        Err(Error::InvalidValue)
210    }
211
212    fn serialize_char(self, _v: char) -> Result<Self::Ok> {
213        Err(Error::InvalidValue)
214    }
215
216    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
217        self.push(b'"')?;
218
219        // Do escaping according to "6. MUST represent all strings (including object member names) in
220        // their minimal-length UTF-8 encoding": https://gibson042.github.io/canonicaljson-spec/
221        //
222        // We don't need to escape lone surrogates because surrogate pairs do not exist in valid UTF-8,
223        // even if they can exist in JSON or JavaScript strings (UCS-2 based). As a result, lone surrogates
224        // cannot exist in a Rust String. If they do, the bug is in the String constructor.
225        // An excellent explanation is available at https://www.youtube.com/watch?v=HhIEDWmQS3w
226
227        // Temporary storage for encoded a single char.
228        // A char is up to 4 bytes long wehn encoded to UTF-8.
229        let mut encoding_tmp = [0u8; 4];
230
231        for c in v.chars() {
232            match c {
233                '\\' => {
234                    self.push(b'\\')?;
235                    self.push(b'\\')?;
236                }
237                '"' => {
238                    self.push(b'\\')?;
239                    self.push(b'"')?;
240                }
241                '\u{0008}' => {
242                    self.push(b'\\')?;
243                    self.push(b'b')?;
244                }
245                '\u{0009}' => {
246                    self.push(b'\\')?;
247                    self.push(b't')?;
248                }
249                '\u{000A}' => {
250                    self.push(b'\\')?;
251                    self.push(b'n')?;
252                }
253                '\u{000C}' => {
254                    self.push(b'\\')?;
255                    self.push(b'f')?;
256                }
257                '\u{000D}' => {
258                    self.push(b'\\')?;
259                    self.push(b'r')?;
260                }
261                '\u{0000}'..='\u{001F}' => {
262                    self.push(b'\\')?;
263                    self.push(b'u')?;
264                    self.push(b'0')?;
265                    self.push(b'0')?;
266                    let (hex1, hex2) = hex(c as u8);
267                    self.push(hex1)?;
268                    self.push(hex2)?;
269                }
270                _ => {
271                    let encoded = c.encode_utf8(&mut encoding_tmp as &mut [u8]);
272                    self.extend_from_slice(encoded.as_bytes())?;
273                }
274            }
275        }
276
277        self.push(b'"')
278    }
279
280    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
281        self.extend_from_slice(v)
282    }
283
284    fn serialize_none(self) -> Result<Self::Ok> {
285        self.extend_from_slice(b"null")
286    }
287
288    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok>
289    where
290        T: ser::Serialize,
291    {
292        value.serialize(self)
293    }
294
295    fn serialize_unit(self) -> Result<Self::Ok> {
296        self.serialize_none()
297    }
298
299    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
300        self.serialize_unit()
301    }
302
303    fn serialize_unit_variant(
304        self,
305        _name: &'static str,
306        _variant_index: u32,
307        variant: &'static str,
308    ) -> Result<Self::Ok> {
309        self.serialize_str(variant)
310    }
311
312    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
313    where
314        T: ser::Serialize,
315    {
316        value.serialize(self)
317    }
318
319    fn serialize_newtype_variant<T: ?Sized>(
320        self,
321        _name: &'static str,
322        _variant_index: u32,
323        variant: &'static str,
324        value: &T,
325    ) -> Result<Self::Ok>
326    where
327        T: ser::Serialize,
328    {
329        self.push(b'{')?;
330        let mut s = SerializeStruct::new(self);
331        s.serialize_field(variant, value)?;
332        s.end()?;
333        Ok(())
334    }
335
336    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
337        self.push(b'[')?;
338
339        Ok(SerializeSeq::new(self))
340    }
341
342    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
343        self.serialize_seq(Some(_len))
344    }
345
346    fn serialize_tuple_struct(
347        self,
348        _name: &'static str,
349        _len: usize,
350    ) -> Result<Self::SerializeTupleStruct> {
351        unreachable!()
352    }
353
354    fn serialize_tuple_variant(
355        self,
356        _name: &'static str,
357        _variant_index: u32,
358        _variant: &'static str,
359        _len: usize,
360    ) -> Result<Self::SerializeTupleVariant> {
361        unreachable!()
362    }
363
364    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
365        self.push(b'{')?;
366
367        Ok(SerializeMap::new(self))
368    }
369
370    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
371        self.push(b'{')?;
372
373        Ok(SerializeStruct::new(self))
374    }
375
376    fn serialize_struct_variant(
377        self,
378        _name: &'static str,
379        _variant_index: u32,
380        variant: &'static str,
381        _len: usize,
382    ) -> Result<Self::SerializeStructVariant> {
383        self.extend_from_slice(b"{\"")?;
384        self.extend_from_slice(variant.as_bytes())?;
385        self.extend_from_slice(b"\":{")?;
386
387        Ok(SerializeStructVariant::new(self))
388    }
389
390    fn collect_str<T: ?Sized>(self, _value: &T) -> Result<Self::Ok>
391    where
392        T: fmt::Display,
393    {
394        unreachable!()
395    }
396}
397
398/// Serializes the given data structure as a string of JSON text
399pub fn to_string<T>(value: &T) -> Result<String>
400where
401    T: ser::Serialize + ?Sized,
402{
403    Ok(unsafe { str::from_utf8_unchecked(&to_vec::<T>(value)?) }.into())
404}
405
406/// Serializes the given data structure as a JSON byte vector
407pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
408where
409    T: ser::Serialize + ?Sized,
410{
411    let mut ser = Serializer::new();
412    value.serialize(&mut ser)?;
413    Ok(ser.buf)
414}
415
416impl ser::Error for Error {
417    fn custom<T>(_msg: T) -> Self
418    where
419        T: fmt::Display,
420    {
421        unreachable!()
422    }
423}
424
425pub(crate) enum Unreachable {}
426
427impl ser::SerializeTupleStruct for Unreachable {
428    type Ok = ();
429    type Error = Error;
430
431    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
432        unreachable!()
433    }
434
435    fn end(self) -> Result<Self::Ok> {
436        unreachable!()
437    }
438}
439
440impl ser::SerializeTupleVariant for Unreachable {
441    type Ok = ();
442    type Error = Error;
443
444    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
445        unreachable!()
446    }
447
448    fn end(self) -> Result<Self::Ok> {
449        unreachable!()
450    }
451}
452
453impl ser::SerializeMap for Unreachable {
454    type Ok = ();
455    type Error = Error;
456
457    fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<()>
458    where
459        T: ser::Serialize,
460    {
461        unreachable!()
462    }
463
464    fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<()>
465    where
466        T: ser::Serialize,
467    {
468        unreachable!()
469    }
470
471    fn end(self) -> Result<Self::Ok> {
472        unreachable!()
473    }
474}
475
476#[cfg(test)]
477mod tests {
478    use serde_derive::Serialize;
479
480    #[test]
481    fn array() {
482        let buf = crate::to_vec(&[0, 1, 2]).unwrap();
483        assert_eq!(buf.len(), 7);
484        assert_eq!(&buf, b"[0,1,2]");
485        assert_eq!(&*crate::to_string(&[0, 1, 2]).unwrap(), "[0,1,2]");
486    }
487
488    #[test]
489    fn bool() {
490        let buf = crate::to_vec(&true).unwrap();
491        assert_eq!(buf.len(), 4);
492        assert_eq!(&buf, b"true");
493
494        assert_eq!(&*crate::to_string(&true).unwrap(), "true");
495    }
496
497    #[test]
498    fn enum_() {
499        #[derive(Serialize)]
500        enum Type {
501            #[serde(rename = "boolean")]
502            Boolean,
503            #[serde(rename = "number")]
504            Number,
505        }
506
507        assert_eq!(
508            &*crate::to_string(&Type::Boolean).unwrap(),
509            r#""boolean""#
510        );
511
512        assert_eq!(
513            &*crate::to_string(&Type::Number).unwrap(),
514            r#""number""#
515        );
516    }
517
518    #[test]
519    fn str() {
520        assert_eq!(&*crate::to_string("hello").unwrap(), r#""hello""#);
521        assert_eq!(&*crate::to_string("").unwrap(), r#""""#);
522
523        // Characters unescaped if possible
524        assert_eq!(&*crate::to_string("ä").unwrap(), r#""ä""#);
525        assert_eq!(&*crate::to_string("৬").unwrap(), r#""৬""#);
526        // assert_eq!(&*crate::to_string("\u{A0}").unwrap(), r#"" ""#); // non-breaking space
527        assert_eq!(&*crate::to_string("ℝ").unwrap(), r#""ℝ""#); // 3 byte character
528        assert_eq!(&*crate::to_string("💣").unwrap(), r#""💣""#); // 4 byte character
529
530        // " and \ must be escaped
531        assert_eq!(
532            &*crate::to_string("foo\"bar").unwrap(),
533            r#""foo\"bar""#
534        );
535        assert_eq!(
536            &*crate::to_string("foo\\bar").unwrap(),
537            r#""foo\\bar""#
538        );
539
540        // \b, \t, \n, \f, \r must be escaped in their two-character escaping
541        assert_eq!(
542            &*crate::to_string(" \u{0008} ").unwrap(),
543            r#"" \b ""#
544        );
545        assert_eq!(
546            &*crate::to_string(" \u{0009} ").unwrap(),
547            r#"" \t ""#
548        );
549        assert_eq!(
550            &*crate::to_string(" \u{000A} ").unwrap(),
551            r#"" \n ""#
552        );
553        assert_eq!(
554            &*crate::to_string(" \u{000C} ").unwrap(),
555            r#"" \f ""#
556        );
557        assert_eq!(
558            &*crate::to_string(" \u{000D} ").unwrap(),
559            r#"" \r ""#
560        );
561
562        // U+0000 through U+001F is escaped using six-character \u00xx uppercase hexadecimal escape sequences
563        assert_eq!(
564            &*crate::to_string(" \u{0000} ").unwrap(),
565            r#"" \u0000 ""#
566        );
567        assert_eq!(
568            &*crate::to_string(" \u{0001} ").unwrap(),
569            r#"" \u0001 ""#
570        );
571        assert_eq!(
572            &*crate::to_string(" \u{0007} ").unwrap(),
573            r#"" \u0007 ""#
574        );
575        assert_eq!(
576            &*crate::to_string(" \u{000e} ").unwrap(),
577            r#"" \u000E ""#
578        );
579        assert_eq!(
580            &*crate::to_string(" \u{001D} ").unwrap(),
581            r#"" \u001D ""#
582        );
583        assert_eq!(
584            &*crate::to_string(" \u{001f} ").unwrap(),
585            r#"" \u001F ""#
586        );
587    }
588
589    #[test]
590    fn struct_bool() {
591        #[derive(Serialize)]
592        struct Led {
593            led: bool,
594        }
595
596        assert_eq!(
597            &*crate::to_string(&Led { led: true }).unwrap(),
598            r#"{"led":true}"#
599        );
600    }
601
602    #[test]
603    fn struct_i8() {
604        #[derive(Serialize)]
605        struct Temperature {
606            temperature: i8,
607        }
608
609        assert_eq!(
610            &*crate::to_string(&Temperature { temperature: 127 }).unwrap(),
611            r#"{"temperature":127}"#
612        );
613
614        assert_eq!(
615            &*crate::to_string(&Temperature { temperature: 20 }).unwrap(),
616            r#"{"temperature":20}"#
617        );
618
619        assert_eq!(
620            &*crate::to_string(&Temperature { temperature: -17 }).unwrap(),
621            r#"{"temperature":-17}"#
622        );
623
624        assert_eq!(
625            &*crate::to_string(&Temperature { temperature: -128 }).unwrap(),
626            r#"{"temperature":-128}"#
627        );
628    }
629
630    #[test]
631    fn struct_f32() {
632        #[derive(Serialize)]
633        struct Temperature {
634            temperature: f32,
635        }
636
637        assert_eq!(
638            &*crate::to_string(&Temperature { temperature: -20. }).unwrap(),
639            r#"{"temperature":-20.0}"#
640        );
641
642        assert_eq!(
643            &*crate::to_string(&Temperature {
644                temperature: -20345.
645            })
646            .unwrap(),
647            r#"{"temperature":-20345.0}"#
648        );
649
650        assert_eq!(
651            &*crate::to_string(&Temperature {
652                temperature: -2.3456789012345e-23
653            })
654            .unwrap(),
655            r#"{"temperature":-2.3456788e-23}"#
656        );
657
658        assert_eq!(
659            &*crate::to_string(&Temperature {
660                temperature: f32::NAN
661            })
662            .unwrap(),
663            r#"{"temperature":null}"#
664        );
665
666        assert_eq!(
667            &*crate::to_string(&Temperature {
668                temperature: f32::NEG_INFINITY
669            })
670            .unwrap(),
671            r#"{"temperature":null}"#
672        );
673    }
674
675    #[test]
676    fn struct_option() {
677        #[derive(Serialize)]
678        struct Property<'a> {
679            description: Option<&'a str>,
680        }
681
682        assert_eq!(
683            crate::to_string(&Property {
684                description: Some("An ambient temperature sensor"),
685            })
686            .unwrap(),
687            r#"{"description":"An ambient temperature sensor"}"#
688        );
689
690        // XXX Ideally this should produce "{}"
691        assert_eq!(
692            crate::to_string(&Property { description: None }).unwrap(),
693            r#"{"description":null}"#
694        );
695    }
696
697    #[test]
698    fn struct_u8() {
699        #[derive(Serialize)]
700        struct Temperature {
701            temperature: u8,
702        }
703
704        assert_eq!(
705            &*crate::to_string(&Temperature { temperature: 20 }).unwrap(),
706            r#"{"temperature":20}"#
707        );
708    }
709
710    #[test]
711    fn struct_() {
712        #[derive(Serialize)]
713        struct Empty {}
714
715        assert_eq!(&*crate::to_string(&Empty {}).unwrap(), r#"{}"#);
716
717        #[derive(Serialize)]
718        struct Tuple {
719            a: bool,
720            b: bool,
721        }
722
723        assert_eq!(
724            &*crate::to_string(&Tuple { a: true, b: false }).unwrap(),
725            r#"{"a":true,"b":false}"#
726        );
727    }
728
729    #[test]
730    fn test_unit() {
731        let a = ();
732        assert_eq!(&*crate::to_string(&a).unwrap(), r#"null"#);
733    }
734
735    #[test]
736    fn test_newtype_struct() {
737        #[derive(Serialize)]
738        struct A(pub u32);
739        let a = A(54);
740        assert_eq!(&*crate::to_string(&a).unwrap(), r#"54"#);
741    }
742
743    #[test]
744    fn test_newtype_variant() {
745        #[derive(Serialize)]
746        enum A {
747            A(u32),
748        }
749        let a = A::A(54);
750
751        assert_eq!(&*crate::to_string(&a).unwrap(), r#"{"A":54}"#);
752    }
753
754    #[test]
755    fn test_struct_variant() {
756        #[derive(Serialize)]
757        enum A {
758            A { x: u32, y: u16 },
759        }
760        let a = A::A { x: 54, y: 720 };
761
762        assert_eq!(
763            &*crate::to_string(&a).unwrap(),
764            r#"{"A":{"x":54,"y":720}}"#
765        );
766    }
767
768    #[test]
769    fn test_serialize_bytes() {
770        use core::fmt::Write;
771        use alloc::string::String;
772
773        pub struct SimpleDecimal(f32);
774
775        impl serde::Serialize for SimpleDecimal {
776            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
777            where
778                S: serde::Serializer,
779            {
780                let mut aux  = String::new();
781                write!(aux, "{:.2}", self.0).unwrap();
782                serializer.serialize_bytes(&aux.as_bytes())
783            }
784        }
785
786        let sd1 = SimpleDecimal(1.55555);
787        assert_eq!(&*crate::to_string(&sd1).unwrap(), r#"1.56"#);
788
789        let sd2 = SimpleDecimal(0.000);
790        assert_eq!(&*crate::to_string(&sd2).unwrap(), r#"0.00"#);
791
792        let sd3 = SimpleDecimal(22222.777777);
793        assert_eq!(&*crate::to_string(&sd3).unwrap(), r#"22222.78"#);
794    }
795}