Skip to main content

simd_json/serde/se/
pp.rs

1use crate::{Error, ErrorType, macros::stry};
2use serde_ext::ser;
3use std::io::Write;
4use std::str;
5use value_trait::generator::BaseGenerator;
6
7use super::key_must_be_a_string;
8
9macro_rules! iomap {
10    ($e:expr_2021) => {
11        ($e).map_err(|err| Error::generic(ErrorType::Io(err)))
12    };
13}
14
15/// Write a value to a vector
16/// # Errors
17/// when the data can not be written
18#[cfg_attr(not(feature = "no-inline"), inline)]
19pub fn to_vec_pretty<T>(to: &T) -> crate::Result<Vec<u8>>
20where
21    T: ser::Serialize + ?Sized,
22{
23    let v = Vec::with_capacity(512);
24    let mut s = PrettySerializer::new(v);
25    to.serialize(&mut s).map(|()| s.writer)
26}
27
28/// Write a value to a string
29///
30/// # Errors
31/// when the data can not be written
32#[cfg_attr(not(feature = "no-inline"), inline)]
33pub fn to_string_pretty<T>(to: &T) -> crate::Result<String>
34where
35    T: ser::Serialize + ?Sized,
36{
37    to_vec_pretty(to).map(|v| unsafe { String::from_utf8_unchecked(v) })
38}
39
40/// Write a value to a string
41/// # Errors
42/// when the data can not be written
43#[cfg_attr(not(feature = "no-inline"), inline)]
44pub fn to_writer_pretty<T, W>(writer: W, to: &T) -> crate::Result<()>
45where
46    T: ser::Serialize + ?Sized,
47    W: Write,
48{
49    let mut s = PrettySerializer::new(writer);
50    to.serialize(&mut s)
51}
52struct PrettySerializer<W: Write> {
53    writer: W,
54    dent: u32,
55}
56impl<W: Write> PrettySerializer<W> {
57    fn new(writer: W) -> Self {
58        Self { writer, dent: 0 }
59    }
60}
61
62impl<W> BaseGenerator for PrettySerializer<W>
63where
64    W: Write,
65{
66    type T = W;
67    #[cfg_attr(not(feature = "no-inline"), inline)]
68    fn get_writer(&mut self) -> &mut Self::T {
69        &mut self.writer
70    }
71    #[cfg_attr(not(feature = "no-inline"), inline)]
72    fn write_min(&mut self, _slice: &[u8], min: u8) -> std::io::Result<()> {
73        self.writer.write_all(&[min])
74    }
75    #[cfg_attr(not(feature = "no-inline"), inline)]
76    fn new_line(&mut self) -> std::io::Result<()> {
77        self.write_char(b'\n').and_then(|()| match self.dent {
78            0 => Ok(()),
79            1 => self.get_writer().write_all(b"  "),
80            2 => self.get_writer().write_all(b"    "),
81            3 => self.get_writer().write_all(b"      "),
82            4 => self.get_writer().write_all(b"        "),
83            5 => self.get_writer().write_all(b"          "),
84            6 => self.get_writer().write_all(b"            "),
85            7 => self.get_writer().write_all(b"              "),
86            8 => self.get_writer().write_all(b"                "),
87            9 => self.get_writer().write_all(b"                  "),
88            _ => {
89                for _ in 0..(self.dent * 2) {
90                    stry!(self.get_writer().write_all(b" "));
91                }
92                Ok(())
93            }
94        })
95    }
96
97    fn indent(&mut self) {
98        self.dent += 1;
99    }
100
101    fn dedent(&mut self) {
102        self.dent -= 1;
103    }
104}
105struct SerializeSeq<'serializer, W: Write + 'serializer> {
106    s: &'serializer mut PrettySerializer<W>,
107    first: bool,
108}
109impl<W> ser::SerializeSeq for SerializeSeq<'_, W>
110where
111    W: Write,
112{
113    type Ok = ();
114    type Error = Error;
115    #[cfg_attr(not(feature = "no-inline"), inline)]
116    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
117    where
118        T: ?Sized + serde_ext::Serialize,
119    {
120        let SerializeSeq {
121            ref mut s,
122            ref mut first,
123            ..
124        } = *self;
125        if *first {
126            *first = false;
127            iomap!(s.new_line()).and_then(|()| value.serialize(&mut **s))
128        } else {
129            iomap!(s.write(b",").and_then(|()| s.new_line()))
130                .and_then(|()| value.serialize(&mut **s))
131        }
132    }
133    #[cfg_attr(not(feature = "no-inline"), inline)]
134    fn end(self) -> Result<Self::Ok, Self::Error> {
135        self.s.dedent();
136        if self.first {
137            iomap!(self.s.write(b"]"))
138        } else {
139            iomap!(self.s.new_line().and_then(|()| self.s.write(b"]")))
140        }
141    }
142}
143
144impl<W> ser::SerializeTuple for SerializeSeq<'_, W>
145where
146    W: Write,
147{
148    type Ok = ();
149    type Error = Error;
150    #[cfg_attr(not(feature = "no-inline"), inline)]
151    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
152    where
153        T: ?Sized + serde_ext::Serialize,
154    {
155        let SerializeSeq {
156            ref mut s,
157            ref mut first,
158        } = *self;
159        if *first {
160            *first = false;
161            iomap!(s.new_line()).and_then(|()| value.serialize(&mut **s))
162        } else {
163            iomap!(s.write(b",").and_then(|()| s.new_line()))
164                .and_then(|()| value.serialize(&mut **s))
165        }
166    }
167    #[cfg_attr(not(feature = "no-inline"), inline)]
168    fn end(self) -> Result<Self::Ok, Self::Error> {
169        self.s.dedent();
170        if self.first {
171            iomap!(self.s.write(b"]"))
172        } else {
173            iomap!(self.s.new_line().and_then(|()| self.s.write(b"]")))
174        }
175    }
176}
177
178impl<W> ser::SerializeTupleStruct for SerializeSeq<'_, W>
179where
180    W: Write,
181{
182    type Ok = ();
183    type Error = Error;
184    #[cfg_attr(not(feature = "no-inline"), inline)]
185    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
186    where
187        T: ?Sized + serde_ext::Serialize,
188    {
189        let SerializeSeq {
190            ref mut s,
191            ref mut first,
192        } = *self;
193        if *first {
194            *first = false;
195            iomap!(s.new_line()).and_then(|()| value.serialize(&mut **s))
196        } else {
197            iomap!(s.write(b",").and_then(|()| s.new_line()))
198                .and_then(|()| value.serialize(&mut **s))
199        }
200    }
201    #[cfg_attr(not(feature = "no-inline"), inline)]
202    fn end(self) -> Result<Self::Ok, Self::Error> {
203        self.s.dedent();
204        if self.first {
205            iomap!(self.s.write(b"]"))
206        } else {
207            iomap!(self.s.new_line().and_then(|()| self.s.write(b"]")))
208        }
209    }
210}
211
212impl<W> ser::SerializeTupleVariant for SerializeSeq<'_, W>
213where
214    W: Write,
215{
216    type Ok = ();
217    type Error = Error;
218    #[cfg_attr(not(feature = "no-inline"), inline)]
219    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
220    where
221        T: ?Sized + serde_ext::Serialize,
222    {
223        let SerializeSeq {
224            ref mut s,
225            ref mut first,
226        } = *self;
227        if *first {
228            *first = false;
229            iomap!(s.new_line()).and_then(|()| value.serialize(&mut **s))
230        } else {
231            iomap!(s.write(b",").and_then(|()| s.new_line()))
232                .and_then(|()| value.serialize(&mut **s))
233        }
234    }
235    #[cfg_attr(not(feature = "no-inline"), inline)]
236    fn end(self) -> Result<Self::Ok, Self::Error> {
237        // close the array of fields, then the `{"Variant": ...}` object around it
238        self.s.dedent();
239        if self.first {
240            iomap!(self.s.write(b"]"))?;
241        } else {
242            iomap!(self.s.new_line().and_then(|()| self.s.write(b"]")))?;
243        }
244        self.s.dedent();
245        iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
246    }
247}
248
249struct MapKeySerializer<'serializer, W: Write + 'serializer> {
250    s: &'serializer mut PrettySerializer<W>,
251}
252
253impl<W> ser::Serializer for MapKeySerializer<'_, W>
254where
255    W: Write,
256{
257    type Ok = ();
258    type Error = Error;
259
260    #[cfg_attr(not(feature = "no-inline"), inline)]
261    fn serialize_str(self, value: &str) -> Result<(), Self::Error> {
262        self.s.serialize_str(value)
263    }
264
265    #[cfg_attr(not(feature = "no-inline"), inline)]
266    fn serialize_unit_variant(
267        self,
268        _name: &'static str,
269        _variant_index: u32,
270        variant: &'static str,
271    ) -> Result<(), Self::Error> {
272        self.s.serialize_str(variant)
273    }
274
275    #[cfg_attr(not(feature = "no-inline"), inline)]
276    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<(), Self::Error>
277    where
278        T: ?Sized + serde_ext::Serialize,
279    {
280        value.serialize(self)
281    }
282
283    type SerializeSeq = ser::Impossible<(), Error>;
284    type SerializeTuple = ser::Impossible<(), Error>;
285    type SerializeTupleStruct = ser::Impossible<(), Error>;
286    type SerializeTupleVariant = ser::Impossible<(), Error>;
287    type SerializeMap = ser::Impossible<(), Error>;
288    type SerializeStruct = ser::Impossible<(), Error>;
289    type SerializeStructVariant = ser::Impossible<(), Error>;
290
291    fn serialize_bool(self, _value: bool) -> Result<(), Self::Error> {
292        Err(key_must_be_a_string())
293    }
294
295    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
296        iomap!(
297            self.s
298                .write_char(b'"')
299                .and_then(|()| self.s.write_int(v))
300                .and_then(|()| self.s.write_char(b'"'))
301        )
302    }
303
304    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
305        iomap!(
306            self.s
307                .write_char(b'"')
308                .and_then(|()| self.s.write_int(v))
309                .and_then(|()| self.s.write_char(b'"'))
310        )
311    }
312
313    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
314        iomap!(
315            self.s
316                .write_char(b'"')
317                .and_then(|()| self.s.write_int(v))
318                .and_then(|()| self.s.write_char(b'"'))
319        )
320    }
321
322    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
323        iomap!(
324            self.s
325                .write_char(b'"')
326                .and_then(|()| self.s.write_int(v))
327                .and_then(|()| self.s.write_char(b'"'))
328        )
329    }
330
331    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
332        iomap!(
333            self.s
334                .write_char(b'"')
335                .and_then(|()| self.s.write_int(v))
336                .and_then(|()| self.s.write_char(b'"'))
337        )
338    }
339
340    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
341        iomap!(
342            self.s
343                .write_char(b'"')
344                .and_then(|()| self.s.write_int(v))
345                .and_then(|()| self.s.write_char(b'"'))
346        )
347    }
348
349    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
350        iomap!(
351            self.s
352                .write_char(b'"')
353                .and_then(|()| self.s.write_int(v))
354                .and_then(|()| self.s.write_char(b'"'))
355        )
356    }
357
358    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
359        iomap!(
360            self.s
361                .write_char(b'"')
362                .and_then(|()| self.s.write_int(v))
363                .and_then(|()| self.s.write_char(b'"'))
364        )
365    }
366
367    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
368        iomap!(
369            self.s
370                .write_char(b'"')
371                .and_then(|()| self.s.write_int(v))
372                .and_then(|()| self.s.write_char(b'"'))
373        )
374    }
375
376    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
377        iomap!(
378            self.s
379                .write_char(b'"')
380                .and_then(|()| self.s.write_int(v))
381                .and_then(|()| self.s.write_char(b'"'))
382        )
383    }
384
385    fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
386        Err(key_must_be_a_string())
387    }
388
389    fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
390        Err(key_must_be_a_string())
391    }
392
393    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
394        self.s.serialize_str(&v.to_string())
395    }
396
397    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
398        Err(key_must_be_a_string())
399    }
400
401    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
402        Err(key_must_be_a_string())
403    }
404
405    fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
406    where
407        T: ?Sized + serde_ext::Serialize,
408    {
409        Err(key_must_be_a_string())
410    }
411
412    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
413        Err(key_must_be_a_string())
414    }
415
416    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
417        Err(key_must_be_a_string())
418    }
419
420    fn serialize_newtype_variant<T>(
421        self,
422        _name: &'static str,
423        _variant_index: u32,
424        _variant: &'static str,
425        _value: &T,
426    ) -> Result<Self::Ok, Self::Error>
427    where
428        T: ?Sized + serde_ext::Serialize,
429    {
430        Err(key_must_be_a_string())
431    }
432
433    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
434        Err(key_must_be_a_string())
435    }
436
437    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
438        Err(key_must_be_a_string())
439    }
440
441    fn serialize_tuple_struct(
442        self,
443        _name: &'static str,
444        _len: usize,
445    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
446        Err(key_must_be_a_string())
447    }
448
449    fn serialize_tuple_variant(
450        self,
451        _name: &'static str,
452        _variant_index: u32,
453        _variant: &'static str,
454        _len: usize,
455    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
456        Err(key_must_be_a_string())
457    }
458
459    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
460        Err(key_must_be_a_string())
461    }
462
463    fn serialize_struct(
464        self,
465        _name: &'static str,
466        _len: usize,
467    ) -> Result<Self::SerializeStruct, Self::Error> {
468        Err(key_must_be_a_string())
469    }
470
471    fn serialize_struct_variant(
472        self,
473        _name: &'static str,
474        _variant_index: u32,
475        _variant: &'static str,
476        _len: usize,
477    ) -> Result<Self::SerializeStructVariant, Self::Error> {
478        Err(key_must_be_a_string())
479    }
480}
481
482struct SerializeMap<'serializer, W: Write + 'serializer> {
483    s: &'serializer mut PrettySerializer<W>,
484    first: bool,
485}
486
487impl<W> ser::SerializeMap for SerializeMap<'_, W>
488where
489    W: Write,
490{
491    type Ok = ();
492    type Error = Error;
493    #[cfg_attr(not(feature = "no-inline"), inline)]
494    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
495    where
496        T: ?Sized + serde_ext::Serialize,
497    {
498        let SerializeMap {
499            ref mut s,
500            ref mut first,
501            ..
502        } = *self;
503
504        if *first {
505            *first = false;
506            iomap!(s.new_line())
507                .and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
508                .and_then(|()| iomap!(s.write(b": ")))
509        } else {
510            iomap!(s.write(b",").and_then(|()| s.new_line()))
511                .and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
512                .and_then(|()| iomap!(s.write(b": ")))
513        }
514    }
515    #[cfg_attr(not(feature = "no-inline"), inline)]
516    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
517    where
518        T: ?Sized + serde_ext::Serialize,
519    {
520        let SerializeMap { ref mut s, .. } = *self;
521        value.serialize(&mut **s)
522    }
523    #[cfg_attr(not(feature = "no-inline"), inline)]
524    fn end(self) -> Result<Self::Ok, Self::Error> {
525        self.s.dedent();
526        if self.first {
527            iomap!(self.s.write(b"}"))
528        } else {
529            iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
530        }
531    }
532}
533
534impl<W> ser::SerializeStruct for SerializeMap<'_, W>
535where
536    W: Write,
537{
538    type Ok = ();
539    type Error = Error;
540    #[cfg_attr(not(feature = "no-inline"), inline)]
541    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
542    where
543        T: ?Sized + serde_ext::Serialize,
544    {
545        let SerializeMap {
546            ref mut s,
547            ref mut first,
548            ..
549        } = *self;
550        if *first {
551            *first = false;
552            iomap!(
553                s.new_line()
554                    .and_then(|()| s.write_simple_string(key))
555                    .and_then(|()| s.write(b": "))
556            )
557            .and_then(|()| value.serialize(&mut **s))
558        } else {
559            iomap!(
560                s.write(b",")
561                    .and_then(|()| s.write_simple_string(key))
562                    .and_then(|()| s.write(b": "))
563            )
564            .and_then(|()| value.serialize(&mut **s))
565        }
566    }
567    #[cfg_attr(not(feature = "no-inline"), inline)]
568    fn end(self) -> Result<Self::Ok, Self::Error> {
569        self.s.dedent();
570        if self.first {
571            iomap!(self.s.write(b"}"))
572        } else {
573            iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
574        }
575    }
576}
577
578struct SerializeStructVariant<'serializer, W: Write + 'serializer> {
579    s: &'serializer mut PrettySerializer<W>,
580    first: bool,
581}
582
583impl<W> ser::SerializeStructVariant for SerializeStructVariant<'_, W>
584where
585    W: Write,
586{
587    type Ok = ();
588    type Error = Error;
589    #[cfg_attr(not(feature = "no-inline"), inline)]
590    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
591    where
592        T: ?Sized + serde_ext::Serialize,
593    {
594        let SerializeStructVariant {
595            ref mut s,
596            ref mut first,
597            ..
598        } = *self;
599        if *first {
600            *first = false;
601            s.indent();
602            iomap!(
603                s.new_line()
604                    .and_then(|()| s.write_simple_string(key))
605                    .and_then(|()| s.write(b": "))
606            )
607            .and_then(|()| value.serialize(&mut **s))
608        } else {
609            iomap!(
610                s.write(b",")
611                    .and_then(|()| s.write_simple_string(key))
612                    .and_then(|()| s.write(b": "))
613            )
614            .and_then(|()| value.serialize(&mut **s))
615        }
616    }
617    #[cfg_attr(not(feature = "no-inline"), inline)]
618    fn end(self) -> Result<Self::Ok, Self::Error> {
619        if self.first {
620            iomap!(self.s.write(b"}"))?;
621        } else {
622            self.s.dedent();
623            iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))?;
624        }
625        self.s.dedent();
626        iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
627    }
628}
629
630impl<'writer, W> ser::Serializer for &'writer mut PrettySerializer<W>
631where
632    W: Write,
633{
634    type Ok = ();
635    type Error = Error;
636    type SerializeSeq = SerializeSeq<'writer, W>;
637    type SerializeTuple = SerializeSeq<'writer, W>;
638    type SerializeTupleStruct = SerializeSeq<'writer, W>;
639    type SerializeTupleVariant = SerializeSeq<'writer, W>;
640    type SerializeMap = SerializeMap<'writer, W>;
641    type SerializeStruct = SerializeMap<'writer, W>;
642    type SerializeStructVariant = SerializeStructVariant<'writer, W>;
643    #[cfg_attr(not(feature = "no-inline"), inline)]
644    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
645        if v {
646            iomap!(self.write(b"true"))
647        } else {
648            iomap!(self.write(b"false"))
649        }
650    }
651    #[cfg_attr(not(feature = "no-inline"), inline)]
652    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
653        iomap!(self.write_int(v))
654    }
655    #[cfg_attr(not(feature = "no-inline"), inline)]
656    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
657        iomap!(self.write_int(v))
658    }
659    #[cfg_attr(not(feature = "no-inline"), inline)]
660    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
661        iomap!(self.write_int(v))
662    }
663    #[cfg_attr(not(feature = "no-inline"), inline)]
664    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
665        iomap!(self.write_int(v))
666    }
667    #[cfg_attr(not(feature = "no-inline"), inline)]
668    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
669        iomap!(self.write_int(v))
670    }
671    #[cfg_attr(not(feature = "no-inline"), inline)]
672    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
673        iomap!(self.write_int(v))
674    }
675    #[cfg_attr(not(feature = "no-inline"), inline)]
676    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
677        iomap!(self.write_int(v))
678    }
679    #[cfg_attr(not(feature = "no-inline"), inline)]
680    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
681        iomap!(self.write_int(v))
682    }
683    #[cfg_attr(not(feature = "no-inline"), inline)]
684    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
685        iomap!(self.write_int(v))
686    }
687    #[cfg_attr(not(feature = "no-inline"), inline)]
688    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
689        iomap!(self.write_int(v))
690    }
691
692    #[cfg_attr(not(feature = "no-inline"), inline)]
693    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
694        iomap!(self.write_float(f64::from(v)))
695    }
696    #[cfg_attr(not(feature = "no-inline"), inline)]
697    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
698        iomap!(self.write_float(v))
699    }
700    #[cfg_attr(not(feature = "no-inline"), inline)]
701    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
702        // A char encoded as UTF-8 takes 4 bytes at most.
703        // taken from: https://docs.serde.rs/src/serde_json/ser.rs.html#213
704        let mut buf = [0; 4];
705        iomap!(self.write_simple_string(v.encode_utf8(&mut buf)))
706    }
707    #[cfg_attr(not(feature = "no-inline"), inline)]
708    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
709        iomap!(self.write_string(v))
710    }
711    #[cfg_attr(not(feature = "no-inline"), inline)]
712    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
713        iomap!(self.write(b"[").and_then(|()| {
714            if let Some((first, rest)) = v.split_first() {
715                self.indent();
716                self.new_line().and_then(|()| {
717                    self.write_int(*first).and_then(|()| {
718                        for v in rest {
719                            self.write(b",").and_then(|()| self.write_int(*v))?;
720                        }
721                        self.dedent();
722                        self.new_line().and_then(|()| self.write(b"]"))
723                    })
724                })
725            } else {
726                self.write(b"]")
727            }
728        }))
729    }
730    #[cfg_attr(not(feature = "no-inline"), inline)]
731    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
732        self.serialize_unit()
733    }
734    #[cfg_attr(not(feature = "no-inline"), inline)]
735    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
736    where
737        T: ?Sized + serde_ext::Serialize,
738    {
739        value.serialize(self)
740    }
741    #[cfg_attr(not(feature = "no-inline"), inline)]
742    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
743        iomap!(self.write(b"null"))
744    }
745    #[cfg_attr(not(feature = "no-inline"), inline)]
746    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
747        self.serialize_unit()
748    }
749    #[cfg_attr(not(feature = "no-inline"), inline)]
750    fn serialize_unit_variant(
751        self,
752        _name: &'static str,
753        _variant_index: u32,
754        variant: &'static str,
755    ) -> Result<Self::Ok, Self::Error> {
756        iomap!(self.write_simple_string(variant))
757    }
758
759    #[cfg_attr(not(feature = "no-inline"), inline)]
760    fn serialize_newtype_struct<T>(
761        self,
762        _name: &'static str,
763        value: &T,
764    ) -> Result<Self::Ok, Self::Error>
765    where
766        T: ?Sized + serde_ext::Serialize,
767    {
768        value.serialize(self)
769    }
770
771    #[cfg_attr(not(feature = "no-inline"), inline)]
772    fn serialize_newtype_variant<T>(
773        self,
774        _name: &'static str,
775        _variant_index: u32,
776        variant: &'static str,
777        value: &T,
778    ) -> Result<Self::Ok, Self::Error>
779    where
780        T: ?Sized + serde_ext::Serialize,
781    {
782        iomap!(
783            self.write(b"{")
784                .and_then(|()| self.write_simple_string(variant))
785                .and_then(|()| self.write(b": "))
786        )
787        .and_then(|()| value.serialize(&mut *self))
788        .and_then(|()| iomap!(self.write(b"}")))
789    }
790    #[cfg_attr(not(feature = "no-inline"), inline)]
791    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
792        self.indent();
793        iomap!(self.write(b"[")).map(move |()| SerializeSeq {
794            s: self,
795            first: true,
796        })
797    }
798
799    #[cfg_attr(not(feature = "no-inline"), inline)]
800    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
801        self.serialize_seq(Some(len))
802    }
803
804    #[cfg_attr(not(feature = "no-inline"), inline)]
805    fn serialize_tuple_struct(
806        self,
807        _name: &'static str,
808        len: usize,
809    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
810        self.serialize_seq(Some(len))
811    }
812
813    #[cfg_attr(not(feature = "no-inline"), inline)]
814    fn serialize_tuple_variant(
815        self,
816        _name: &'static str,
817        _variant_index: u32,
818        variant: &'static str,
819        len: usize,
820    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
821        self.indent();
822        iomap!(
823            self.write(b"{")
824                .and_then(|()| self.new_line())
825                .and_then(|()| self.write_simple_string(variant))
826                .and_then(|()| self.write(b": "))
827        )
828        .and_then(move |()| self.serialize_seq(Some(len)))
829    }
830
831    #[cfg_attr(not(feature = "no-inline"), inline)]
832    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
833        self.indent();
834        iomap!(self.write(b"{")).map(move |()| SerializeMap {
835            s: self,
836            first: true,
837        })
838    }
839
840    #[cfg_attr(not(feature = "no-inline"), inline)]
841    fn serialize_struct(
842        self,
843        _name: &'static str,
844        len: usize,
845    ) -> Result<Self::SerializeStruct, Self::Error> {
846        self.serialize_map(Some(len))
847    }
848
849    #[cfg_attr(not(feature = "no-inline"), inline)]
850    fn serialize_struct_variant(
851        self,
852        _name: &'static str,
853        _variant_index: u32,
854        variant: &'static str,
855        _len: usize,
856    ) -> Result<Self::SerializeStructVariant, Self::Error> {
857        self.indent();
858        iomap!(
859            self.write(b"{")
860                .and_then(|()| self.new_line())
861                .and_then(|()| self.write_simple_string(variant))
862                .and_then(|()| self.write(b": {"))
863        )
864        .map(move |()| SerializeStructVariant {
865            s: self,
866            first: true,
867        })
868    }
869}
870
871#[cfg(test)]
872mod test {
873    #![allow(clippy::ignored_unit_patterns, unused_imports)]
874    use crate::OwnedValue as Value;
875    #[cfg(not(target_arch = "wasm32"))]
876    use crate::StaticNode;
877    use crate::from_slice;
878    #[cfg(not(target_arch = "wasm32"))]
879    use proptest::prelude::*;
880    #[test]
881    fn pretty_print_serde() {
882        #[derive(Clone, Debug, PartialEq, serde::Serialize)]
883        enum Segment {
884            Id { mid: usize },
885        }
886
887        assert_eq!(
888            "{\n  \"Id\": {\n    \"mid\": 0\n  }\n}",
889            crate::to_string_pretty(&Segment::Id { mid: 0 }).expect("to_string_pretty")
890        );
891    }
892
893    #[test]
894    fn pretty_print_empty_containers_of_unknown_length() {
895        use std::collections::BTreeMap;
896
897        // `collect_seq` over a filter passes `len: None`
898        struct Filtered(Vec<u8>);
899        impl serde::Serialize for Filtered {
900            fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
901                s.collect_seq(self.0.iter().filter(|x| **x > 10))
902            }
903        }
904        #[derive(serde::Serialize)]
905        struct Flat {
906            #[serde(flatten)]
907            rest: BTreeMap<String, u8>,
908        }
909
910        assert_eq!(
911            crate::to_string_pretty(&Filtered(vec![1, 2])).expect("to_string_pretty"),
912            "[]"
913        );
914        assert_eq!(
915            crate::to_string_pretty(&vec![Filtered(vec![1]), Filtered(vec![2])])
916                .expect("to_string_pretty"),
917            "[\n  [],\n  []\n]"
918        );
919        assert_eq!(
920            crate::to_string_pretty(&Flat {
921                rest: BTreeMap::new()
922            })
923            .expect("to_string_pretty"),
924            "{}"
925        );
926    }
927
928    #[test]
929    fn pretty_print_empty_and_nonempty_containers() {
930        #[derive(serde::Serialize)]
931        struct Empty {}
932        #[derive(serde::Serialize)]
933        struct One {
934            a: u8,
935        }
936        #[derive(serde::Serialize)]
937        struct Ts(u8, u8);
938        #[derive(serde::Serialize)]
939        struct Ts0();
940        #[derive(serde::Serialize)]
941        enum E {
942            S0 {},
943            S { a: u8 },
944        }
945        fn same<T: serde::Serialize>(v: &T) {
946            assert_eq!(
947                crate::to_string_pretty(v).expect("to_string_pretty"),
948                serde_json::to_string_pretty(v).expect("serde_json")
949            );
950        }
951
952        same(&(1u8, 2u8));
953        same(&[0u8; 0]);
954        same(&Ts(1, 2));
955        same(&Ts0());
956        same(&Empty {});
957        same(&One { a: 1 });
958        same(&E::S0 {});
959        same(&E::S { a: 1 });
960    }
961
962    #[test]
963    fn pretty_print_tuple_variant() {
964        // The array of a tuple variant was closed with `}` and the enclosing object was never
965        // closed: `{"C": [1, "s" }`, not JSON.
966        #[derive(Clone, Debug, PartialEq, serde::Serialize)]
967        enum E {
968            C(i64, String),
969            Z(),
970        }
971
972        assert_eq!(
973            "{\n  \"C\": [\n    1,\n    \"s\"\n  ]\n}",
974            crate::to_string_pretty(&E::C(1, "s".into())).expect("to_string_pretty")
975        );
976        assert_eq!(
977            "{\n  \"Z\": []\n}",
978            crate::to_string_pretty(&E::Z()).expect("to_string_pretty")
979        );
980        // and nested in an array, which must still parse and match serde_json
981        let v = vec![E::C(1, "a".into()), E::C(2, "b".into())];
982        let pretty = crate::to_string_pretty(&v).expect("to_string_pretty");
983        assert_eq!(
984            pretty,
985            serde_json::to_string_pretty(&v).expect("serde_json")
986        );
987    }
988
989    #[test]
990    fn numerical_map_serde() {
991        use std::collections::HashMap;
992
993        #[derive(Clone, Debug, PartialEq, serde::Serialize)]
994        struct Foo {
995            pub bar: HashMap<i32, i32>,
996        }
997
998        let mut foo = Foo {
999            bar: HashMap::new(),
1000        };
1001
1002        foo.bar.insert(1337, 1337);
1003
1004        assert_eq!(
1005            r#"{
1006  "bar": {
1007    "1337": 1337
1008  }
1009}"#,
1010            crate::to_string_pretty(&foo).expect("to_string_pretty")
1011        );
1012    }
1013
1014    #[cfg(not(feature = "128bit"))]
1015    #[cfg(not(target_arch = "wasm32"))]
1016    fn arb_json_value() -> BoxedStrategy<Value> {
1017        let leaf = prop_oneof![
1018            Just(Value::Static(StaticNode::Null)),
1019            any::<bool>().prop_map(Value::from),
1020            //(-1.0e306f64..1.0e306f64).prop_map(Value::from), // damn you float!
1021            any::<i8>().prop_map(Value::from),
1022            any::<i16>().prop_map(Value::from),
1023            any::<i32>().prop_map(Value::from),
1024            any::<i64>().prop_map(Value::from),
1025            any::<u8>().prop_map(Value::from),
1026            any::<u16>().prop_map(Value::from),
1027            any::<u32>().prop_map(Value::from),
1028            any::<u64>().prop_map(Value::from),
1029            ".*".prop_map(Value::from),
1030        ];
1031        leaf.prop_recursive(
1032            8,   // 8 levels deep
1033            256, // Shoot for maximum size of 256 nodes
1034            10,  // We put up to 10 items per collection
1035            |inner| {
1036                prop_oneof![
1037                    // Take the inner strategy and make the two recursive cases.
1038                    prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
1039                    prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
1040                ]
1041            },
1042        )
1043        .boxed()
1044    }
1045
1046    #[cfg(feature = "128bit")]
1047    #[cfg(not(target_arch = "wasm32"))]
1048    fn arb_json_value() -> BoxedStrategy<Value> {
1049        let leaf = prop_oneof![
1050            Just(Value::Static(StaticNode::Null)),
1051            any::<bool>().prop_map(Value::from),
1052            //(-1.0e306f64..1.0e306f64).prop_map(Value::from), // damn you float!
1053            any::<i8>().prop_map(Value::from),
1054            any::<i16>().prop_map(Value::from),
1055            any::<i32>().prop_map(Value::from),
1056            any::<i64>().prop_map(Value::from),
1057            any::<u8>().prop_map(Value::from),
1058            any::<u16>().prop_map(Value::from),
1059            any::<u32>().prop_map(Value::from),
1060            any::<u64>().prop_map(Value::from),
1061            any::<i128>().prop_map(Value::from),
1062            any::<u128>().prop_map(Value::from),
1063            ".*".prop_map(Value::from),
1064        ];
1065        leaf.prop_recursive(
1066            8,   // 8 levels deep
1067            256, // Shoot for maximum size of 256 nodes
1068            10,  // We put up to 10 items per collection
1069            |inner| {
1070                prop_oneof![
1071                    // Take the inner strategy and make the two recursive cases.
1072                    prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
1073                    prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
1074                ]
1075            },
1076        )
1077        .boxed()
1078    }
1079
1080    #[cfg(not(target_arch = "wasm32"))]
1081    proptest! {
1082        #![proptest_config(ProptestConfig {
1083            // Setting both fork and timeout is redundant since timeout implies
1084            // fork, but both are shown for clarity.
1085            // Disabled for code coverage, enable to track bugs
1086            // fork: true,
1087            .. ProptestConfig::default()
1088        })]
1089
1090        #[test]
1091        fn prop_json_encode_decode(val in arb_json_value()) {
1092            let mut encoded = crate::to_vec_pretty(&val).expect("to_vec_pretty");
1093            println!("{}", String::from_utf8_lossy(&encoded.clone()));
1094            let res: Value = crate::from_slice(encoded.as_mut_slice()).expect("can't convert");
1095            assert_eq!(val, res);
1096        }
1097        #[test]
1098        fn prop_serd_compat(val in arb_json_value()) {
1099            let simd = crate::to_string_pretty(&val).expect("to_string_pretty");
1100            let serde = serde_json::to_string_pretty(&val).expect("to_string_pretty");
1101            assert_eq!(simd, serde);
1102        }
1103    }
1104
1105    #[test]
1106    fn prettyfy() {
1107        let v = crate::json!({"key1":{}, "key2":[], "key3":[1,{"key4":null}]});
1108        let mut res = match crate::to_vec_pretty(&v) {
1109            Ok(res) => res,
1110            Err(e) => {
1111                println!("prettify: {e}");
1112                assert_eq!(v, "snot");
1113                vec![]
1114            }
1115        };
1116        let s = unsafe { String::from_utf8_unchecked(res.clone()) };
1117        println!("{s}");
1118        let v2: Value = from_slice(&mut res).expect("generated bad json");
1119        assert_eq!(v, v2);
1120    }
1121}