serde_json_core_fmt/ser/
mod.rs

1//! Serialize a Rust data structure into JSON data
2
3use core::fmt;
4
5use serde::ser;
6use serde::ser::SerializeStruct as _;
7
8mod map;
9mod sequence;
10mod struct_;
11
12use self::map::SerializeMap;
13use self::sequence::SerializeSeq;
14use self::struct_::{SerializeStruct, SerializeStructVariant};
15
16pub(crate) struct Serializer<W: fmt::Write>(W);
17
18impl<W: fmt::Write> Serializer<W> {
19    fn char(&mut self, c: char) -> fmt::Result {
20        self.0.write_char(c)
21    }
22
23    fn str(&mut self, string: &str) -> fmt::Result {
24        self.0.write_str(string)
25    }
26}
27
28/// Upper-case hex for value in 0..16, encoded as ASCII bytes
29impl<'a, W: fmt::Write> ser::Serializer for &'a mut Serializer<W> {
30    type Ok = ();
31    type Error = fmt::Error;
32    type SerializeSeq = SerializeSeq<'a, W>;
33    type SerializeTuple = SerializeSeq<'a, W>;
34    type SerializeTupleStruct = Unreachable;
35    type SerializeTupleVariant = Unreachable;
36    type SerializeMap = SerializeMap<'a, W>;
37    type SerializeStruct = SerializeStruct<'a, W>;
38    type SerializeStructVariant = SerializeStructVariant<'a, W>;
39
40    fn serialize_bool(self, v: bool) -> fmt::Result {
41        self.str(if v { "true" } else { "false" })
42    }
43
44    fn serialize_i8(self, v: i8) -> fmt::Result {
45        write!(self.0, "{}", v)
46    }
47
48    fn serialize_i16(self, v: i16) -> fmt::Result {
49        write!(self.0, "{}", v)
50    }
51
52    fn serialize_i32(self, v: i32) -> fmt::Result {
53        write!(self.0, "{}", v)
54    }
55
56    fn serialize_i64(self, v: i64) -> fmt::Result {
57        write!(self.0, "{}", v)
58    }
59
60    fn serialize_u8(self, v: u8) -> fmt::Result {
61        write!(self.0, "{}", v)
62    }
63
64    fn serialize_u16(self, v: u16) -> fmt::Result {
65        write!(self.0, "{}", v)
66    }
67
68    fn serialize_u32(self, v: u32) -> fmt::Result {
69        write!(self.0, "{}", v)
70    }
71
72    fn serialize_u64(self, v: u64) -> fmt::Result {
73        write!(self.0, "{}", v)
74    }
75
76    fn serialize_f32(self, v: f32) -> fmt::Result {
77        self.str(ryu::Buffer::new().format(v))
78    }
79
80    fn serialize_f64(self, v: f64) -> fmt::Result {
81        self.str(ryu::Buffer::new().format(v))
82    }
83
84    fn serialize_char(self, c: char) -> fmt::Result {
85        // Do escaping according to "6. MUST represent all strings (including object member names) in
86        // their minimal-length UTF-8 encoding": https://gibson042.github.io/canonicaljson-spec/
87        //
88        // We don't need to escape lone surrogates because surrogate pairs do not exist in valid UTF-8,
89        // even if they can exist in JSON or JavaScript strings (UCS-2 based). As a result, lone surrogates
90        // cannot exist in a Rust String. If they do, the bug is in the String constructor.
91        // An excellent explanation is available at https://www.youtube.com/watch?v=HhIEDWmQS3w
92        match c {
93            '\\' | '"' => write!(self.0, "\\{}", c),
94            '\u{8}' => self.str("\\b"),
95            '\t' => self.str("\\t"),
96            '\n' => self.str("\\n"),
97            '\u{B}' => self.str("\\v"),
98            '\u{C}' => self.str("\\f"),
99            '\r' => self.str("\\r"),
100            '\u{0}'..='\u{1F}' => {
101                write!(self.0, "\\u{:04x}", c as u32)
102            }
103            _ => self.char(c),
104        }
105    }
106
107    fn serialize_str(self, v: &str) -> fmt::Result {
108        self.char('"')?;
109        for c in v.chars() {
110            self.serialize_char(c)?;
111        }
112        self.char('"')
113    }
114
115    fn serialize_bytes(self, v: &[u8]) -> fmt::Result {
116        self.str(unsafe { core::str::from_utf8_unchecked(v) })
117    }
118
119    fn serialize_none(self) -> fmt::Result {
120        self.str("null")
121    }
122
123    fn serialize_some<T: ser::Serialize + ?Sized>(self, value: &T) -> fmt::Result {
124        value.serialize(self)
125    }
126
127    fn serialize_unit(self) -> fmt::Result {
128        self.serialize_none()
129    }
130
131    fn serialize_unit_struct(self, _name: &'static str) -> fmt::Result {
132        self.serialize_unit()
133    }
134
135    fn serialize_unit_variant(
136        self,
137        _name: &'static str,
138        _variant_index: u32,
139        variant: &'static str,
140    ) -> fmt::Result {
141        self.serialize_str(variant)
142    }
143
144    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> fmt::Result
145    where
146        T: ser::Serialize + ?Sized,
147    {
148        value.serialize(self)
149    }
150
151    fn serialize_newtype_variant<T: ser::Serialize + ?Sized>(
152        mut self,
153        _name: &'static str,
154        _variant_index: u32,
155        variant: &'static str,
156        value: &T,
157    ) -> fmt::Result {
158        self.char('{')?;
159        let mut s = SerializeStruct::new(&mut self);
160        s.serialize_field(variant, value)?;
161        s.end()
162    }
163
164    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, fmt::Error> {
165        self.char('[')?;
166        Ok(SerializeSeq::new(self))
167    }
168
169    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, fmt::Error> {
170        self.serialize_seq(Some(len))
171    }
172
173    fn serialize_tuple_struct(
174        self,
175        _name: &'static str,
176        _len: usize,
177    ) -> Result<Self::SerializeTupleStruct, fmt::Error> {
178        unreachable!()
179    }
180
181    fn serialize_tuple_variant(
182        self,
183        _name: &'static str,
184        _variant_index: u32,
185        _variant: &'static str,
186        _len: usize,
187    ) -> Result<Self::SerializeTupleVariant, fmt::Error> {
188        unreachable!()
189    }
190
191    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, fmt::Error> {
192        self.char('{')?;
193        Ok(SerializeMap::new(self))
194    }
195
196    fn serialize_struct(
197        self,
198        _name: &'static str,
199        _len: usize,
200    ) -> Result<Self::SerializeStruct, fmt::Error> {
201        self.char('{')?;
202        Ok(SerializeStruct::new(self))
203    }
204
205    fn serialize_struct_variant(
206        self,
207        _name: &'static str,
208        _variant_index: u32,
209        variant: &'static str,
210        _len: usize,
211    ) -> Result<Self::SerializeStructVariant, fmt::Error> {
212        write!(self.0, "{{\"{}\":{{", variant)?;
213        Ok(SerializeStructVariant::new(self))
214    }
215
216    fn collect_str<T: fmt::Display + ?Sized>(self, _value: &T) -> fmt::Result {
217        unreachable!()
218    }
219}
220
221/// Create a serializable formatter
222pub fn to_fmt<W: fmt::Write, T: ser::Serialize + ?Sized>(w: W, value: &T) -> fmt::Result {
223    let mut serializer = Serializer(w);
224    value.serialize(&mut serializer)
225}
226
227pub(crate) enum Unreachable {}
228
229impl ser::SerializeTupleStruct for Unreachable {
230    type Ok = ();
231    type Error = fmt::Error;
232
233    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> fmt::Result {
234        unreachable!()
235    }
236
237    fn end(self) -> fmt::Result {
238        unreachable!()
239    }
240}
241
242impl ser::SerializeTupleVariant for Unreachable {
243    type Ok = ();
244    type Error = fmt::Error;
245
246    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> fmt::Result {
247        unreachable!()
248    }
249
250    fn end(self) -> fmt::Result {
251        unreachable!()
252    }
253}
254
255impl ser::SerializeMap for Unreachable {
256    type Ok = ();
257    type Error = fmt::Error;
258
259    fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> fmt::Result
260    where
261        T: ser::Serialize,
262    {
263        unreachable!()
264    }
265
266    fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> fmt::Result
267    where
268        T: ser::Serialize,
269    {
270        unreachable!()
271    }
272
273    fn end(self) -> fmt::Result {
274        unreachable!()
275    }
276}
277
278#[cfg(test)]
279mod tests {
280    use serde_derive::Serialize;
281
282    struct Wrapper<T: serde::Serialize>(T);
283
284    impl<T: serde::Serialize> core::fmt::Display for Wrapper<T> {
285        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
286            crate::to_fmt(f, &self.0)
287        }
288    }
289
290    #[test]
291    fn array() {
292        assert_eq!(format!("{}", Wrapper([0, 1, 2])), "[0,1,2]");
293    }
294
295    #[test]
296    fn bool() {
297        assert_eq!(format!("{}", Wrapper(true)), "true");
298    }
299
300    #[test]
301    fn enum_() {
302        #[derive(Serialize)]
303        enum Type {
304            #[serde(rename = "boolean")]
305            Boolean,
306            #[serde(rename = "number")]
307            Number,
308        }
309
310        assert_eq!(format!("{}", Wrapper(Type::Boolean)), r#""boolean""#);
311
312        assert_eq!(format!("{}", Wrapper(Type::Number)), r#""number""#);
313    }
314
315    #[test]
316    fn str() {
317        assert_eq!(format!("{}", Wrapper("hello")), r#""hello""#);
318        assert_eq!(format!("{}", Wrapper("")), r#""""#);
319
320        // Characters unescaped if possible
321        assert_eq!(format!("{}", Wrapper("ä")), r#""ä""#);
322        assert_eq!(format!("{}", Wrapper("৬")), r#""৬""#);
323        // assert_eq!(format!("{}", Wrapper("\u{A0}")), r#"" ""#); // non-breaking space
324        assert_eq!(format!("{}", Wrapper("ℝ")), r#""ℝ""#); // 3 byte character
325        assert_eq!(format!("{}", Wrapper("💣")), r#""💣""#); // 4 byte character
326
327        // " and \ must be escaped
328        assert_eq!(format!("{}", Wrapper("foo\"bar")), r#""foo\"bar""#);
329        assert_eq!(format!("{}", Wrapper("foo\\bar")), r#""foo\\bar""#);
330
331        // \b, \t, \n, \f, \r must be escaped in their two-character escaping
332        assert_eq!(format!("{}", Wrapper(" \u{8} ")), r#"" \b ""#);
333        assert_eq!(format!("{}", Wrapper(" \u{9} ")), r#"" \t ""#);
334        assert_eq!(format!("{}", Wrapper(" \u{A} ")), r#"" \n ""#);
335        assert_eq!(format!("{}", Wrapper(" \u{C} ")), r#"" \f ""#);
336        assert_eq!(format!("{}", Wrapper(" \u{D} ")), r#"" \r ""#);
337
338        // U+0000 through U+001F is escaped using six-character \u00xx uppercase hexadecimal escape sequences
339        assert_eq!(format!("{}", Wrapper(" \u{00} ")), r#"" \u0000 ""#);
340        assert_eq!(format!("{}", Wrapper(" \u{01} ")), r#"" \u0001 ""#);
341        assert_eq!(format!("{}", Wrapper(" \u{07} ")), r#"" \u0007 ""#);
342        assert_eq!(format!("{}", Wrapper(" \u{0e} ")), r#"" \u000e ""#);
343        assert_eq!(format!("{}", Wrapper(" \u{1D} ")), r#"" \u001d ""#);
344        assert_eq!(format!("{}", Wrapper(" \u{1f} ")), r#"" \u001f ""#);
345    }
346
347    #[test]
348    fn struct_bool() {
349        #[derive(Serialize)]
350        struct Led {
351            led: bool,
352        }
353
354        assert_eq!(format!("{}", Wrapper(&Led { led: true })), r#"{"led":true}"#);
355    }
356
357    #[test]
358    fn struct_i8() {
359        #[derive(Serialize)]
360        struct Temperature {
361            temperature: i8,
362        }
363
364        assert_eq!(
365            format!("{}", Wrapper(&Temperature { temperature: 127 })),
366            r#"{"temperature":127}"#
367        );
368
369        assert_eq!(
370            format!("{}", Wrapper(&Temperature { temperature: 20 })),
371            r#"{"temperature":20}"#
372        );
373
374        assert_eq!(
375            format!("{}", Wrapper(&Temperature { temperature: -17 })),
376            r#"{"temperature":-17}"#
377        );
378
379        assert_eq!(
380            format!("{}", Wrapper(&Temperature { temperature: -128 })),
381            r#"{"temperature":-128}"#
382        );
383    }
384
385    #[test]
386    fn struct_f32() {
387        #[derive(Serialize)]
388        struct Temperature {
389            temperature: f32,
390        }
391
392        assert_eq!(
393            format!("{}", Wrapper(&Temperature { temperature: -20. })),
394            r#"{"temperature":-20.0}"#
395        );
396
397        assert_eq!(
398            format!("{}", Wrapper(&Temperature { temperature: -20345. })),
399            r#"{"temperature":-20345.0}"#
400        );
401
402        assert_eq!(
403            format!("{}", Wrapper(&Temperature { temperature: -2.3456789012345e-23 })),
404            r#"{"temperature":-2.3456788e-23}"#
405        );
406    }
407
408    #[test]
409    fn struct_option() {
410        #[derive(Serialize)]
411        struct Property<'a> {
412            description: Option<&'a str>,
413        }
414
415        assert_eq!(
416            format!(
417                "{}",
418                Wrapper(&Property { description: Some("An ambient temperature sensor") })
419            ),
420            r#"{"description":"An ambient temperature sensor"}"#
421        );
422
423        // XXX Ideally this should produce "{}"
424        assert_eq!(
425            format!("{}", Wrapper(&Property { description: None })),
426            r#"{"description":null}"#
427        );
428    }
429
430    #[test]
431    fn struct_u8() {
432        #[derive(Serialize)]
433        struct Temperature {
434            temperature: u8,
435        }
436
437        assert_eq!(
438            format!("{}", Wrapper(&Temperature { temperature: 20 })),
439            r#"{"temperature":20}"#
440        );
441    }
442
443    #[test]
444    fn struct_() {
445        #[derive(Serialize)]
446        struct Empty {}
447
448        assert_eq!(format!("{}", Wrapper(&Empty {})), r#"{}"#);
449
450        #[derive(Serialize)]
451        struct Tuple {
452            a: bool,
453            b: bool,
454        }
455
456        assert_eq!(format!("{}", Wrapper(&Tuple { a: true, b: false })), r#"{"a":true,"b":false}"#);
457    }
458
459    #[test]
460    fn test_unit() {
461        let a = ();
462        assert_eq!(format!("{}", Wrapper(&a)), r#"null"#);
463    }
464
465    #[test]
466    fn test_newtype_struct() {
467        #[derive(Serialize)]
468        struct A(pub u32);
469        let a = A(54);
470        assert_eq!(format!("{}", Wrapper(&a)), r#"54"#);
471    }
472
473    #[test]
474    fn test_newtype_variant() {
475        #[derive(Serialize)]
476        enum A {
477            A(u32),
478        }
479        let a = A::A(54);
480
481        assert_eq!(format!("{}", Wrapper(&a)), r#"{"A":54}"#);
482    }
483
484    #[test]
485    fn test_struct_variant() {
486        #[derive(Serialize)]
487        enum A {
488            A { x: u32, y: u16 },
489        }
490        let a = A::A { x: 54, y: 720 };
491
492        assert_eq!(format!("{}", Wrapper(&a)), r#"{"A":{"x":54,"y":720}}"#);
493    }
494
495    #[test]
496    fn test_serialize_bytes() {
497        pub struct SimpleDecimal(f32);
498
499        impl serde::Serialize for SimpleDecimal {
500            fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
501                let string = format!("{:.2}", self.0);
502                serializer.serialize_bytes(string.as_bytes())
503            }
504        }
505
506        let sd1 = SimpleDecimal(1.55555);
507        assert_eq!(format!("{}", Wrapper(&sd1)), r#"1.56"#);
508
509        let sd2 = SimpleDecimal(0.000);
510        assert_eq!(format!("{}", Wrapper(&sd2)), r#"0.00"#);
511
512        let sd3 = SimpleDecimal(22222.777777);
513        assert_eq!(format!("{}", Wrapper(&sd3)), r#"22222.78"#);
514    }
515}