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#[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#[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#[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 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 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 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 #[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 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 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, 256, 10, |inner| {
1036 prop_oneof![
1037 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 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, 256, 10, |inner| {
1070 prop_oneof![
1071 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 .. 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}