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 if self.first {
136 Ok(())
137 } else {
138 self.s.dedent();
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 if self.first {
170 Ok(())
171 } else {
172 self.s.dedent();
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 if self.first {
204 Ok(())
205 } else {
206 self.s.dedent();
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 if self.first {
238 Ok(())
239 } else {
240 self.s.dedent();
241 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
242 }
243 }
244}
245
246struct MapKeySerializer<'serializer, W: Write + 'serializer> {
247 s: &'serializer mut PrettySerializer<W>,
248}
249
250impl<W> ser::Serializer for MapKeySerializer<'_, W>
251where
252 W: Write,
253{
254 type Ok = ();
255 type Error = Error;
256
257 #[cfg_attr(not(feature = "no-inline"), inline)]
258 fn serialize_str(self, value: &str) -> Result<(), Self::Error> {
259 dbg!(value);
260 self.s.serialize_str(value)
261 }
262
263 #[cfg_attr(not(feature = "no-inline"), inline)]
264 fn serialize_unit_variant(
265 self,
266 _name: &'static str,
267 _variant_index: u32,
268 variant: &'static str,
269 ) -> Result<(), Self::Error> {
270 self.s.serialize_str(variant)
271 }
272
273 #[cfg_attr(not(feature = "no-inline"), inline)]
274 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<(), Self::Error>
275 where
276 T: ?Sized + serde_ext::Serialize,
277 {
278 value.serialize(self)
279 }
280
281 type SerializeSeq = ser::Impossible<(), Error>;
282 type SerializeTuple = ser::Impossible<(), Error>;
283 type SerializeTupleStruct = ser::Impossible<(), Error>;
284 type SerializeTupleVariant = ser::Impossible<(), Error>;
285 type SerializeMap = ser::Impossible<(), Error>;
286 type SerializeStruct = ser::Impossible<(), Error>;
287 type SerializeStructVariant = ser::Impossible<(), Error>;
288
289 fn serialize_bool(self, _value: bool) -> Result<(), Self::Error> {
290 Err(key_must_be_a_string())
291 }
292
293 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
294 iomap!(
295 self.s
296 .write_char(b'"')
297 .and_then(|()| self.s.write_int(v))
298 .and_then(|()| self.s.write_char(b'"'))
299 )
300 }
301
302 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
303 iomap!(
304 self.s
305 .write_char(b'"')
306 .and_then(|()| self.s.write_int(v))
307 .and_then(|()| self.s.write_char(b'"'))
308 )
309 }
310
311 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
312 iomap!(
313 self.s
314 .write_char(b'"')
315 .and_then(|()| self.s.write_int(v))
316 .and_then(|()| self.s.write_char(b'"'))
317 )
318 }
319
320 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
321 iomap!(
322 self.s
323 .write_char(b'"')
324 .and_then(|()| self.s.write_int(v))
325 .and_then(|()| self.s.write_char(b'"'))
326 )
327 }
328
329 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
330 iomap!(
331 self.s
332 .write_char(b'"')
333 .and_then(|()| self.s.write_int(v))
334 .and_then(|()| self.s.write_char(b'"'))
335 )
336 }
337
338 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
339 iomap!(
340 self.s
341 .write_char(b'"')
342 .and_then(|()| self.s.write_int(v))
343 .and_then(|()| self.s.write_char(b'"'))
344 )
345 }
346
347 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
348 iomap!(
349 self.s
350 .write_char(b'"')
351 .and_then(|()| self.s.write_int(v))
352 .and_then(|()| self.s.write_char(b'"'))
353 )
354 }
355
356 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
357 iomap!(
358 self.s
359 .write_char(b'"')
360 .and_then(|()| self.s.write_int(v))
361 .and_then(|()| self.s.write_char(b'"'))
362 )
363 }
364
365 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
366 iomap!(
367 self.s
368 .write_char(b'"')
369 .and_then(|()| self.s.write_int(v))
370 .and_then(|()| self.s.write_char(b'"'))
371 )
372 }
373
374 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
375 iomap!(
376 self.s
377 .write_char(b'"')
378 .and_then(|()| self.s.write_int(v))
379 .and_then(|()| self.s.write_char(b'"'))
380 )
381 }
382
383 fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
384 Err(key_must_be_a_string())
385 }
386
387 fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
388 Err(key_must_be_a_string())
389 }
390
391 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
392 self.s.serialize_str(&v.to_string())
393 }
394
395 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
396 Err(key_must_be_a_string())
397 }
398
399 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
400 Err(key_must_be_a_string())
401 }
402
403 fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
404 where
405 T: ?Sized + serde_ext::Serialize,
406 {
407 Err(key_must_be_a_string())
408 }
409
410 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
411 Err(key_must_be_a_string())
412 }
413
414 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
415 Err(key_must_be_a_string())
416 }
417
418 fn serialize_newtype_variant<T>(
419 self,
420 _name: &'static str,
421 _variant_index: u32,
422 _variant: &'static str,
423 _value: &T,
424 ) -> Result<Self::Ok, Self::Error>
425 where
426 T: ?Sized + serde_ext::Serialize,
427 {
428 Err(key_must_be_a_string())
429 }
430
431 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
432 Err(key_must_be_a_string())
433 }
434
435 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
436 Err(key_must_be_a_string())
437 }
438
439 fn serialize_tuple_struct(
440 self,
441 _name: &'static str,
442 _len: usize,
443 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
444 Err(key_must_be_a_string())
445 }
446
447 fn serialize_tuple_variant(
448 self,
449 _name: &'static str,
450 _variant_index: u32,
451 _variant: &'static str,
452 _len: usize,
453 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
454 Err(key_must_be_a_string())
455 }
456
457 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
458 Err(key_must_be_a_string())
459 }
460
461 fn serialize_struct(
462 self,
463 _name: &'static str,
464 _len: usize,
465 ) -> Result<Self::SerializeStruct, Self::Error> {
466 Err(key_must_be_a_string())
467 }
468
469 fn serialize_struct_variant(
470 self,
471 _name: &'static str,
472 _variant_index: u32,
473 _variant: &'static str,
474 _len: usize,
475 ) -> Result<Self::SerializeStructVariant, Self::Error> {
476 Err(key_must_be_a_string())
477 }
478}
479
480struct SerializeMap<'serializer, W: Write + 'serializer> {
481 s: &'serializer mut PrettySerializer<W>,
482 first: bool,
483}
484
485impl<W> ser::SerializeMap for SerializeMap<'_, W>
486where
487 W: Write,
488{
489 type Ok = ();
490 type Error = Error;
491 #[cfg_attr(not(feature = "no-inline"), inline)]
492 fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
493 where
494 T: ?Sized + serde_ext::Serialize,
495 {
496 let SerializeMap {
497 ref mut s,
498 ref mut first,
499 ..
500 } = *self;
501
502 if *first {
503 *first = false;
504 iomap!(s.new_line())
505 .and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
506 .and_then(|()| iomap!(s.write(b": ")))
507 } else {
508 iomap!(s.write(b",").and_then(|()| s.new_line()))
509 .and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
510 .and_then(|()| iomap!(s.write(b": ")))
511 }
512 }
513 #[cfg_attr(not(feature = "no-inline"), inline)]
514 fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
515 where
516 T: ?Sized + serde_ext::Serialize,
517 {
518 let SerializeMap { ref mut s, .. } = *self;
519 value.serialize(&mut **s)
520 }
521 #[cfg_attr(not(feature = "no-inline"), inline)]
522 fn end(self) -> Result<Self::Ok, Self::Error> {
523 if self.first {
524 Ok(())
525 } else {
526 self.s.dedent();
527 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
528 }
529 }
530}
531
532impl<W> ser::SerializeStruct for SerializeMap<'_, W>
533where
534 W: Write,
535{
536 type Ok = ();
537 type Error = Error;
538 #[cfg_attr(not(feature = "no-inline"), inline)]
539 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
540 where
541 T: ?Sized + serde_ext::Serialize,
542 {
543 let SerializeMap {
544 ref mut s,
545 ref mut first,
546 ..
547 } = *self;
548 if *first {
549 *first = false;
550 iomap!(
551 s.new_line()
552 .and_then(|()| s.write_simple_string(key))
553 .and_then(|()| s.write(b": "))
554 )
555 .and_then(|()| value.serialize(&mut **s))
556 } else {
557 iomap!(
558 s.write(b",")
559 .and_then(|()| s.write_simple_string(key))
560 .and_then(|()| s.write(b": "))
561 )
562 .and_then(|()| value.serialize(&mut **s))
563 }
564 }
565 #[cfg_attr(not(feature = "no-inline"), inline)]
566 fn end(self) -> Result<Self::Ok, Self::Error> {
567 if self.first {
568 Ok(())
569 } else {
570 self.s.dedent();
571 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
572 }
573 }
574}
575
576struct SerializeStructVariant<'serializer, W: Write + 'serializer> {
577 s: &'serializer mut PrettySerializer<W>,
578 first: bool,
579}
580
581impl<W> ser::SerializeStructVariant for SerializeStructVariant<'_, W>
582where
583 W: Write,
584{
585 type Ok = ();
586 type Error = Error;
587 #[cfg_attr(not(feature = "no-inline"), inline)]
588 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
589 where
590 T: ?Sized + serde_ext::Serialize,
591 {
592 let SerializeStructVariant {
593 ref mut s,
594 ref mut first,
595 ..
596 } = *self;
597 if *first {
598 *first = false;
599 s.indent();
600 iomap!(
601 s.new_line()
602 .and_then(|()| s.write_simple_string(key))
603 .and_then(|()| s.write(b": "))
604 )
605 .and_then(|()| value.serialize(&mut **s))
606 } else {
607 iomap!(
608 s.write(b",")
609 .and_then(|()| s.write_simple_string(key))
610 .and_then(|()| s.write(b": "))
611 )
612 .and_then(|()| value.serialize(&mut **s))
613 }
614 }
615 #[cfg_attr(not(feature = "no-inline"), inline)]
616 fn end(self) -> Result<Self::Ok, Self::Error> {
617 self.s.dedent();
618 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}"))).and_then(move |()| {
619 if self.first {
620 Ok(())
621 } else {
622 self.s.dedent();
623
624 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
625 }
626 })
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 if len == Some(0) {
793 iomap!(self.write(b"[]"))
794 } else {
795 self.indent();
796 iomap!(self.write(b"["))
797 }
798 .map(move |()| SerializeSeq {
799 s: self,
800 first: true,
801 })
802 }
803
804 #[cfg_attr(not(feature = "no-inline"), inline)]
805 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
806 self.serialize_seq(Some(len))
807 }
808
809 #[cfg_attr(not(feature = "no-inline"), inline)]
810 fn serialize_tuple_struct(
811 self,
812 _name: &'static str,
813 len: usize,
814 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
815 self.serialize_seq(Some(len))
816 }
817
818 #[cfg_attr(not(feature = "no-inline"), inline)]
819 fn serialize_tuple_variant(
820 self,
821 _name: &'static str,
822 _variant_index: u32,
823 variant: &'static str,
824 len: usize,
825 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
826 self.indent();
827 iomap!(
828 self.write(b"{")
829 .and_then(|()| self.new_line())
830 .and_then(|()| self.write_simple_string(variant))
831 .and_then(|()| self.write(b": "))
832 )
833 .and_then(move |()| self.serialize_seq(Some(len)))
834 }
835
836 #[cfg_attr(not(feature = "no-inline"), inline)]
837 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
838 if len == Some(0) {
839 iomap!(self.write(b"{}"))
840 } else {
841 self.indent();
842 iomap!(self.write(b"{"))
843 }
844 .map(move |()| SerializeMap {
845 s: self,
846 first: true,
847 })
848 }
849
850 #[cfg_attr(not(feature = "no-inline"), inline)]
851 fn serialize_struct(
852 self,
853 _name: &'static str,
854 len: usize,
855 ) -> Result<Self::SerializeStruct, Self::Error> {
856 self.serialize_map(Some(len))
857 }
858
859 #[cfg_attr(not(feature = "no-inline"), inline)]
860 fn serialize_struct_variant(
861 self,
862 _name: &'static str,
863 _variant_index: u32,
864 variant: &'static str,
865 len: usize,
866 ) -> Result<Self::SerializeStructVariant, Self::Error> {
867 self.indent();
868 iomap!(
869 self.write(b"{")
870 .and_then(|()| self.new_line())
871 .and_then(|()| self.write_simple_string(variant))
872 .and_then(|()| self.write(b": "))
873 )
874 .and_then(move |()| {
875 if len == 0 {
876 iomap!(self.write(b"{}"))
877 } else {
878 iomap!(self.write(b"{"))
879 }
880 .map(move |()| SerializeStructVariant {
881 s: self,
882 first: true,
883 })
884 })
885 }
886}
887
888#[cfg(test)]
889mod test {
890 #![allow(clippy::ignored_unit_patterns, unused_imports)]
891 use crate::OwnedValue as Value;
892 #[cfg(not(target_arch = "wasm32"))]
893 use crate::StaticNode;
894 use crate::from_slice;
895 #[cfg(not(target_arch = "wasm32"))]
896 use proptest::prelude::*;
897 #[test]
898 fn pretty_print_serde() {
899 #[derive(Clone, Debug, PartialEq, serde::Serialize)]
900 enum Segment {
901 Id { mid: usize },
902 }
903
904 assert_eq!(
905 "{\n \"Id\": {\n \"mid\": 0\n }\n}",
906 crate::to_string_pretty(&Segment::Id { mid: 0 }).expect("to_string_pretty")
907 );
908 }
909
910 #[test]
911 fn numerical_map_serde() {
912 use std::collections::HashMap;
913
914 #[derive(Clone, Debug, PartialEq, serde::Serialize)]
915 struct Foo {
916 pub bar: HashMap<i32, i32>,
917 }
918
919 let mut foo = Foo {
920 bar: HashMap::new(),
921 };
922
923 foo.bar.insert(1337, 1337);
924
925 assert_eq!(
926 r#"{
927 "bar": {
928 "1337": 1337
929 }
930}"#,
931 crate::to_string_pretty(&foo).expect("to_string_pretty")
932 );
933 }
934
935 #[cfg(not(feature = "128bit"))]
936 #[cfg(not(target_arch = "wasm32"))]
937 fn arb_json_value() -> BoxedStrategy<Value> {
938 let leaf = prop_oneof![
939 Just(Value::Static(StaticNode::Null)),
940 any::<bool>().prop_map(Value::from),
941 any::<i8>().prop_map(Value::from),
943 any::<i16>().prop_map(Value::from),
944 any::<i32>().prop_map(Value::from),
945 any::<i64>().prop_map(Value::from),
946 any::<u8>().prop_map(Value::from),
947 any::<u16>().prop_map(Value::from),
948 any::<u32>().prop_map(Value::from),
949 any::<u64>().prop_map(Value::from),
950 ".*".prop_map(Value::from),
951 ];
952 leaf.prop_recursive(
953 8, 256, 10, |inner| {
957 prop_oneof![
958 prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
960 prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
961 ]
962 },
963 )
964 .boxed()
965 }
966
967 #[cfg(feature = "128bit")]
968 #[cfg(not(target_arch = "wasm32"))]
969 fn arb_json_value() -> BoxedStrategy<Value> {
970 let leaf = prop_oneof![
971 Just(Value::Static(StaticNode::Null)),
972 any::<bool>().prop_map(Value::from),
973 any::<i8>().prop_map(Value::from),
975 any::<i16>().prop_map(Value::from),
976 any::<i32>().prop_map(Value::from),
977 any::<i64>().prop_map(Value::from),
978 any::<u8>().prop_map(Value::from),
979 any::<u16>().prop_map(Value::from),
980 any::<u32>().prop_map(Value::from),
981 any::<u64>().prop_map(Value::from),
982 any::<i128>().prop_map(Value::from),
983 any::<u128>().prop_map(Value::from),
984 ".*".prop_map(Value::from),
985 ];
986 leaf.prop_recursive(
987 8, 256, 10, |inner| {
991 prop_oneof![
992 prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
994 prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
995 ]
996 },
997 )
998 .boxed()
999 }
1000
1001 #[cfg(not(target_arch = "wasm32"))]
1002 proptest! {
1003 #![proptest_config(ProptestConfig {
1004 .. ProptestConfig::default()
1009 })]
1010
1011 #[test]
1012 fn prop_json_encode_decode(val in arb_json_value()) {
1013 let mut encoded = crate::to_vec_pretty(&val).expect("to_vec_pretty");
1014 println!("{}", String::from_utf8_lossy(&encoded.clone()));
1015 let res: Value = crate::from_slice(encoded.as_mut_slice()).expect("can't convert");
1016 assert_eq!(val, res);
1017 }
1018 #[test]
1019 fn prop_serd_compat(val in arb_json_value()) {
1020 let simd = crate::to_string_pretty(&val).expect("to_string_pretty");
1021 let serde = serde_json::to_string_pretty(&val).expect("to_string_pretty");
1022 assert_eq!(simd, serde);
1023 }
1024 }
1025
1026 #[test]
1027 fn prettyfy() {
1028 let v = crate::json!({"key1":{}, "key2":[], "key3":[1,{"key4":null}]});
1029 let mut res = match crate::to_vec_pretty(&v) {
1030 Ok(res) => res,
1031 Err(e) => {
1032 println!("prettify: {e}");
1033 assert_eq!(v, "snot");
1034 vec![]
1035 }
1036 };
1037 let s = unsafe { String::from_utf8_unchecked(res.clone()) };
1038 println!("{s}");
1039 let v2: Value = from_slice(&mut res).expect("generated bad json");
1040 assert_eq!(v, v2);
1041 }
1042}