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 self.s.serialize_str(value)
260 }
261
262 #[cfg_attr(not(feature = "no-inline"), inline)]
263 fn serialize_unit_variant(
264 self,
265 _name: &'static str,
266 _variant_index: u32,
267 variant: &'static str,
268 ) -> Result<(), Self::Error> {
269 self.s.serialize_str(variant)
270 }
271
272 #[cfg_attr(not(feature = "no-inline"), inline)]
273 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<(), Self::Error>
274 where
275 T: ?Sized + serde_ext::Serialize,
276 {
277 value.serialize(self)
278 }
279
280 type SerializeSeq = ser::Impossible<(), Error>;
281 type SerializeTuple = ser::Impossible<(), Error>;
282 type SerializeTupleStruct = ser::Impossible<(), Error>;
283 type SerializeTupleVariant = ser::Impossible<(), Error>;
284 type SerializeMap = ser::Impossible<(), Error>;
285 type SerializeStruct = ser::Impossible<(), Error>;
286 type SerializeStructVariant = ser::Impossible<(), Error>;
287
288 fn serialize_bool(self, _value: bool) -> Result<(), Self::Error> {
289 Err(key_must_be_a_string())
290 }
291
292 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
293 iomap!(
294 self.s
295 .write_char(b'"')
296 .and_then(|()| self.s.write_int(v))
297 .and_then(|()| self.s.write_char(b'"'))
298 )
299 }
300
301 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
302 iomap!(
303 self.s
304 .write_char(b'"')
305 .and_then(|()| self.s.write_int(v))
306 .and_then(|()| self.s.write_char(b'"'))
307 )
308 }
309
310 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
311 iomap!(
312 self.s
313 .write_char(b'"')
314 .and_then(|()| self.s.write_int(v))
315 .and_then(|()| self.s.write_char(b'"'))
316 )
317 }
318
319 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
320 iomap!(
321 self.s
322 .write_char(b'"')
323 .and_then(|()| self.s.write_int(v))
324 .and_then(|()| self.s.write_char(b'"'))
325 )
326 }
327
328 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
329 iomap!(
330 self.s
331 .write_char(b'"')
332 .and_then(|()| self.s.write_int(v))
333 .and_then(|()| self.s.write_char(b'"'))
334 )
335 }
336
337 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
338 iomap!(
339 self.s
340 .write_char(b'"')
341 .and_then(|()| self.s.write_int(v))
342 .and_then(|()| self.s.write_char(b'"'))
343 )
344 }
345
346 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
347 iomap!(
348 self.s
349 .write_char(b'"')
350 .and_then(|()| self.s.write_int(v))
351 .and_then(|()| self.s.write_char(b'"'))
352 )
353 }
354
355 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
356 iomap!(
357 self.s
358 .write_char(b'"')
359 .and_then(|()| self.s.write_int(v))
360 .and_then(|()| self.s.write_char(b'"'))
361 )
362 }
363
364 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
365 iomap!(
366 self.s
367 .write_char(b'"')
368 .and_then(|()| self.s.write_int(v))
369 .and_then(|()| self.s.write_char(b'"'))
370 )
371 }
372
373 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
374 iomap!(
375 self.s
376 .write_char(b'"')
377 .and_then(|()| self.s.write_int(v))
378 .and_then(|()| self.s.write_char(b'"'))
379 )
380 }
381
382 fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
383 Err(key_must_be_a_string())
384 }
385
386 fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
387 Err(key_must_be_a_string())
388 }
389
390 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
391 self.s.serialize_str(&v.to_string())
392 }
393
394 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
395 Err(key_must_be_a_string())
396 }
397
398 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
399 Err(key_must_be_a_string())
400 }
401
402 fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
403 where
404 T: ?Sized + serde_ext::Serialize,
405 {
406 Err(key_must_be_a_string())
407 }
408
409 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
410 Err(key_must_be_a_string())
411 }
412
413 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
414 Err(key_must_be_a_string())
415 }
416
417 fn serialize_newtype_variant<T>(
418 self,
419 _name: &'static str,
420 _variant_index: u32,
421 _variant: &'static str,
422 _value: &T,
423 ) -> Result<Self::Ok, Self::Error>
424 where
425 T: ?Sized + serde_ext::Serialize,
426 {
427 Err(key_must_be_a_string())
428 }
429
430 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
431 Err(key_must_be_a_string())
432 }
433
434 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
435 Err(key_must_be_a_string())
436 }
437
438 fn serialize_tuple_struct(
439 self,
440 _name: &'static str,
441 _len: usize,
442 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
443 Err(key_must_be_a_string())
444 }
445
446 fn serialize_tuple_variant(
447 self,
448 _name: &'static str,
449 _variant_index: u32,
450 _variant: &'static str,
451 _len: usize,
452 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
453 Err(key_must_be_a_string())
454 }
455
456 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
457 Err(key_must_be_a_string())
458 }
459
460 fn serialize_struct(
461 self,
462 _name: &'static str,
463 _len: usize,
464 ) -> Result<Self::SerializeStruct, Self::Error> {
465 Err(key_must_be_a_string())
466 }
467
468 fn serialize_struct_variant(
469 self,
470 _name: &'static str,
471 _variant_index: u32,
472 _variant: &'static str,
473 _len: usize,
474 ) -> Result<Self::SerializeStructVariant, Self::Error> {
475 Err(key_must_be_a_string())
476 }
477}
478
479struct SerializeMap<'serializer, W: Write + 'serializer> {
480 s: &'serializer mut PrettySerializer<W>,
481 first: bool,
482}
483
484impl<W> ser::SerializeMap for SerializeMap<'_, W>
485where
486 W: Write,
487{
488 type Ok = ();
489 type Error = Error;
490 #[cfg_attr(not(feature = "no-inline"), inline)]
491 fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
492 where
493 T: ?Sized + serde_ext::Serialize,
494 {
495 let SerializeMap {
496 ref mut s,
497 ref mut first,
498 ..
499 } = *self;
500
501 if *first {
502 *first = false;
503 iomap!(s.new_line())
504 .and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
505 .and_then(|()| iomap!(s.write(b": ")))
506 } else {
507 iomap!(s.write(b",").and_then(|()| s.new_line()))
508 .and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
509 .and_then(|()| iomap!(s.write(b": ")))
510 }
511 }
512 #[cfg_attr(not(feature = "no-inline"), inline)]
513 fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
514 where
515 T: ?Sized + serde_ext::Serialize,
516 {
517 let SerializeMap { ref mut s, .. } = *self;
518 value.serialize(&mut **s)
519 }
520 #[cfg_attr(not(feature = "no-inline"), inline)]
521 fn end(self) -> Result<Self::Ok, Self::Error> {
522 if self.first {
523 Ok(())
524 } else {
525 self.s.dedent();
526 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
527 }
528 }
529}
530
531impl<W> ser::SerializeStruct for SerializeMap<'_, W>
532where
533 W: Write,
534{
535 type Ok = ();
536 type Error = Error;
537 #[cfg_attr(not(feature = "no-inline"), inline)]
538 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
539 where
540 T: ?Sized + serde_ext::Serialize,
541 {
542 let SerializeMap {
543 ref mut s,
544 ref mut first,
545 ..
546 } = *self;
547 if *first {
548 *first = false;
549 iomap!(
550 s.new_line()
551 .and_then(|()| s.write_simple_string(key))
552 .and_then(|()| s.write(b": "))
553 )
554 .and_then(|()| value.serialize(&mut **s))
555 } else {
556 iomap!(
557 s.write(b",")
558 .and_then(|()| s.write_simple_string(key))
559 .and_then(|()| s.write(b": "))
560 )
561 .and_then(|()| value.serialize(&mut **s))
562 }
563 }
564 #[cfg_attr(not(feature = "no-inline"), inline)]
565 fn end(self) -> Result<Self::Ok, Self::Error> {
566 if self.first {
567 Ok(())
568 } else {
569 self.s.dedent();
570 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
571 }
572 }
573}
574
575struct SerializeStructVariant<'serializer, W: Write + 'serializer> {
576 s: &'serializer mut PrettySerializer<W>,
577 first: bool,
578}
579
580impl<W> ser::SerializeStructVariant for SerializeStructVariant<'_, W>
581where
582 W: Write,
583{
584 type Ok = ();
585 type Error = Error;
586 #[cfg_attr(not(feature = "no-inline"), inline)]
587 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
588 where
589 T: ?Sized + serde_ext::Serialize,
590 {
591 let SerializeStructVariant {
592 ref mut s,
593 ref mut first,
594 ..
595 } = *self;
596 if *first {
597 *first = false;
598 s.indent();
599 iomap!(
600 s.new_line()
601 .and_then(|()| s.write_simple_string(key))
602 .and_then(|()| s.write(b": "))
603 )
604 .and_then(|()| value.serialize(&mut **s))
605 } else {
606 iomap!(
607 s.write(b",")
608 .and_then(|()| s.write_simple_string(key))
609 .and_then(|()| s.write(b": "))
610 )
611 .and_then(|()| value.serialize(&mut **s))
612 }
613 }
614 #[cfg_attr(not(feature = "no-inline"), inline)]
615 fn end(self) -> Result<Self::Ok, Self::Error> {
616 self.s.dedent();
617 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}"))).and_then(move |()| {
618 if self.first {
619 Ok(())
620 } else {
621 self.s.dedent();
622
623 iomap!(self.s.new_line().and_then(|()| self.s.write(b"}")))
624 }
625 })
626 }
627}
628
629impl<'writer, W> ser::Serializer for &'writer mut PrettySerializer<W>
630where
631 W: Write,
632{
633 type Ok = ();
634 type Error = Error;
635 type SerializeSeq = SerializeSeq<'writer, W>;
636 type SerializeTuple = SerializeSeq<'writer, W>;
637 type SerializeTupleStruct = SerializeSeq<'writer, W>;
638 type SerializeTupleVariant = SerializeSeq<'writer, W>;
639 type SerializeMap = SerializeMap<'writer, W>;
640 type SerializeStruct = SerializeMap<'writer, W>;
641 type SerializeStructVariant = SerializeStructVariant<'writer, W>;
642 #[cfg_attr(not(feature = "no-inline"), inline)]
643 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
644 if v {
645 iomap!(self.write(b"true"))
646 } else {
647 iomap!(self.write(b"false"))
648 }
649 }
650 #[cfg_attr(not(feature = "no-inline"), inline)]
651 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
652 iomap!(self.write_int(v))
653 }
654 #[cfg_attr(not(feature = "no-inline"), inline)]
655 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
656 iomap!(self.write_int(v))
657 }
658 #[cfg_attr(not(feature = "no-inline"), inline)]
659 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
660 iomap!(self.write_int(v))
661 }
662 #[cfg_attr(not(feature = "no-inline"), inline)]
663 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
664 iomap!(self.write_int(v))
665 }
666 #[cfg_attr(not(feature = "no-inline"), inline)]
667 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
668 iomap!(self.write_int(v))
669 }
670 #[cfg_attr(not(feature = "no-inline"), inline)]
671 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
672 iomap!(self.write_int(v))
673 }
674 #[cfg_attr(not(feature = "no-inline"), inline)]
675 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
676 iomap!(self.write_int(v))
677 }
678 #[cfg_attr(not(feature = "no-inline"), inline)]
679 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
680 iomap!(self.write_int(v))
681 }
682 #[cfg_attr(not(feature = "no-inline"), inline)]
683 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
684 iomap!(self.write_int(v))
685 }
686 #[cfg_attr(not(feature = "no-inline"), inline)]
687 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
688 iomap!(self.write_int(v))
689 }
690
691 #[cfg_attr(not(feature = "no-inline"), inline)]
692 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
693 iomap!(self.write_float(f64::from(v)))
694 }
695 #[cfg_attr(not(feature = "no-inline"), inline)]
696 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
697 iomap!(self.write_float(v))
698 }
699 #[cfg_attr(not(feature = "no-inline"), inline)]
700 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
701 let mut buf = [0; 4];
704 iomap!(self.write_simple_string(v.encode_utf8(&mut buf)))
705 }
706 #[cfg_attr(not(feature = "no-inline"), inline)]
707 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
708 iomap!(self.write_string(v))
709 }
710 #[cfg_attr(not(feature = "no-inline"), inline)]
711 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
712 iomap!(self.write(b"[").and_then(|()| {
713 if let Some((first, rest)) = v.split_first() {
714 self.indent();
715 self.new_line().and_then(|()| {
716 self.write_int(*first).and_then(|()| {
717 for v in rest {
718 self.write(b",").and_then(|()| self.write_int(*v))?;
719 }
720 self.dedent();
721 self.new_line().and_then(|()| self.write(b"]"))
722 })
723 })
724 } else {
725 self.write(b"]")
726 }
727 }))
728 }
729 #[cfg_attr(not(feature = "no-inline"), inline)]
730 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
731 self.serialize_unit()
732 }
733 #[cfg_attr(not(feature = "no-inline"), inline)]
734 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
735 where
736 T: ?Sized + serde_ext::Serialize,
737 {
738 value.serialize(self)
739 }
740 #[cfg_attr(not(feature = "no-inline"), inline)]
741 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
742 iomap!(self.write(b"null"))
743 }
744 #[cfg_attr(not(feature = "no-inline"), inline)]
745 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
746 self.serialize_unit()
747 }
748 #[cfg_attr(not(feature = "no-inline"), inline)]
749 fn serialize_unit_variant(
750 self,
751 _name: &'static str,
752 _variant_index: u32,
753 variant: &'static str,
754 ) -> Result<Self::Ok, Self::Error> {
755 iomap!(self.write_simple_string(variant))
756 }
757
758 #[cfg_attr(not(feature = "no-inline"), inline)]
759 fn serialize_newtype_struct<T>(
760 self,
761 _name: &'static str,
762 value: &T,
763 ) -> Result<Self::Ok, Self::Error>
764 where
765 T: ?Sized + serde_ext::Serialize,
766 {
767 value.serialize(self)
768 }
769
770 #[cfg_attr(not(feature = "no-inline"), inline)]
771 fn serialize_newtype_variant<T>(
772 self,
773 _name: &'static str,
774 _variant_index: u32,
775 variant: &'static str,
776 value: &T,
777 ) -> Result<Self::Ok, Self::Error>
778 where
779 T: ?Sized + serde_ext::Serialize,
780 {
781 iomap!(
782 self.write(b"{")
783 .and_then(|()| self.write_simple_string(variant))
784 .and_then(|()| self.write(b": "))
785 )
786 .and_then(|()| value.serialize(&mut *self))
787 .and_then(|()| iomap!(self.write(b"}")))
788 }
789 #[cfg_attr(not(feature = "no-inline"), inline)]
790 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
791 if len == Some(0) {
792 iomap!(self.write(b"[]"))
793 } else {
794 self.indent();
795 iomap!(self.write(b"["))
796 }
797 .map(move |()| SerializeSeq {
798 s: self,
799 first: true,
800 })
801 }
802
803 #[cfg_attr(not(feature = "no-inline"), inline)]
804 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
805 self.serialize_seq(Some(len))
806 }
807
808 #[cfg_attr(not(feature = "no-inline"), inline)]
809 fn serialize_tuple_struct(
810 self,
811 _name: &'static str,
812 len: usize,
813 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
814 self.serialize_seq(Some(len))
815 }
816
817 #[cfg_attr(not(feature = "no-inline"), inline)]
818 fn serialize_tuple_variant(
819 self,
820 _name: &'static str,
821 _variant_index: u32,
822 variant: &'static str,
823 len: usize,
824 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
825 self.indent();
826 iomap!(
827 self.write(b"{")
828 .and_then(|()| self.new_line())
829 .and_then(|()| self.write_simple_string(variant))
830 .and_then(|()| self.write(b": "))
831 )
832 .and_then(move |()| self.serialize_seq(Some(len)))
833 }
834
835 #[cfg_attr(not(feature = "no-inline"), inline)]
836 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
837 if len == Some(0) {
838 iomap!(self.write(b"{}"))
839 } else {
840 self.indent();
841 iomap!(self.write(b"{"))
842 }
843 .map(move |()| SerializeMap {
844 s: self,
845 first: true,
846 })
847 }
848
849 #[cfg_attr(not(feature = "no-inline"), inline)]
850 fn serialize_struct(
851 self,
852 _name: &'static str,
853 len: usize,
854 ) -> Result<Self::SerializeStruct, Self::Error> {
855 self.serialize_map(Some(len))
856 }
857
858 #[cfg_attr(not(feature = "no-inline"), inline)]
859 fn serialize_struct_variant(
860 self,
861 _name: &'static str,
862 _variant_index: u32,
863 variant: &'static str,
864 len: usize,
865 ) -> Result<Self::SerializeStructVariant, Self::Error> {
866 self.indent();
867 iomap!(
868 self.write(b"{")
869 .and_then(|()| self.new_line())
870 .and_then(|()| self.write_simple_string(variant))
871 .and_then(|()| self.write(b": "))
872 )
873 .and_then(move |()| {
874 if len == 0 {
875 iomap!(self.write(b"{}"))
876 } else {
877 iomap!(self.write(b"{"))
878 }
879 .map(move |()| SerializeStructVariant {
880 s: self,
881 first: true,
882 })
883 })
884 }
885}
886
887#[cfg(test)]
888mod test {
889 #![allow(clippy::ignored_unit_patterns, unused_imports)]
890 use crate::OwnedValue as Value;
891 #[cfg(not(target_arch = "wasm32"))]
892 use crate::StaticNode;
893 use crate::from_slice;
894 #[cfg(not(target_arch = "wasm32"))]
895 use proptest::prelude::*;
896 #[test]
897 fn pretty_print_serde() {
898 #[derive(Clone, Debug, PartialEq, serde::Serialize)]
899 enum Segment {
900 Id { mid: usize },
901 }
902
903 assert_eq!(
904 "{\n \"Id\": {\n \"mid\": 0\n }\n}",
905 crate::to_string_pretty(&Segment::Id { mid: 0 }).expect("to_string_pretty")
906 );
907 }
908
909 #[test]
910 fn numerical_map_serde() {
911 use std::collections::HashMap;
912
913 #[derive(Clone, Debug, PartialEq, serde::Serialize)]
914 struct Foo {
915 pub bar: HashMap<i32, i32>,
916 }
917
918 let mut foo = Foo {
919 bar: HashMap::new(),
920 };
921
922 foo.bar.insert(1337, 1337);
923
924 assert_eq!(
925 r#"{
926 "bar": {
927 "1337": 1337
928 }
929}"#,
930 crate::to_string_pretty(&foo).expect("to_string_pretty")
931 );
932 }
933
934 #[cfg(not(feature = "128bit"))]
935 #[cfg(not(target_arch = "wasm32"))]
936 fn arb_json_value() -> BoxedStrategy<Value> {
937 let leaf = prop_oneof![
938 Just(Value::Static(StaticNode::Null)),
939 any::<bool>().prop_map(Value::from),
940 any::<i8>().prop_map(Value::from),
942 any::<i16>().prop_map(Value::from),
943 any::<i32>().prop_map(Value::from),
944 any::<i64>().prop_map(Value::from),
945 any::<u8>().prop_map(Value::from),
946 any::<u16>().prop_map(Value::from),
947 any::<u32>().prop_map(Value::from),
948 any::<u64>().prop_map(Value::from),
949 ".*".prop_map(Value::from),
950 ];
951 leaf.prop_recursive(
952 8, 256, 10, |inner| {
956 prop_oneof![
957 prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
959 prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
960 ]
961 },
962 )
963 .boxed()
964 }
965
966 #[cfg(feature = "128bit")]
967 #[cfg(not(target_arch = "wasm32"))]
968 fn arb_json_value() -> BoxedStrategy<Value> {
969 let leaf = prop_oneof![
970 Just(Value::Static(StaticNode::Null)),
971 any::<bool>().prop_map(Value::from),
972 any::<i8>().prop_map(Value::from),
974 any::<i16>().prop_map(Value::from),
975 any::<i32>().prop_map(Value::from),
976 any::<i64>().prop_map(Value::from),
977 any::<u8>().prop_map(Value::from),
978 any::<u16>().prop_map(Value::from),
979 any::<u32>().prop_map(Value::from),
980 any::<u64>().prop_map(Value::from),
981 any::<i128>().prop_map(Value::from),
982 any::<u128>().prop_map(Value::from),
983 ".*".prop_map(Value::from),
984 ];
985 leaf.prop_recursive(
986 8, 256, 10, |inner| {
990 prop_oneof![
991 prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
993 prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
994 ]
995 },
996 )
997 .boxed()
998 }
999
1000 #[cfg(not(target_arch = "wasm32"))]
1001 proptest! {
1002 #![proptest_config(ProptestConfig {
1003 .. ProptestConfig::default()
1008 })]
1009
1010 #[test]
1011 fn prop_json_encode_decode(val in arb_json_value()) {
1012 let mut encoded = crate::to_vec_pretty(&val).expect("to_vec_pretty");
1013 println!("{}", String::from_utf8_lossy(&encoded.clone()));
1014 let res: Value = crate::from_slice(encoded.as_mut_slice()).expect("can't convert");
1015 assert_eq!(val, res);
1016 }
1017 #[test]
1018 fn prop_serd_compat(val in arb_json_value()) {
1019 let simd = crate::to_string_pretty(&val).expect("to_string_pretty");
1020 let serde = serde_json::to_string_pretty(&val).expect("to_string_pretty");
1021 assert_eq!(simd, serde);
1022 }
1023 }
1024
1025 #[test]
1026 fn prettyfy() {
1027 let v = crate::json!({"key1":{}, "key2":[], "key3":[1,{"key4":null}]});
1028 let mut res = match crate::to_vec_pretty(&v) {
1029 Ok(res) => res,
1030 Err(e) => {
1031 println!("prettify: {e}");
1032 assert_eq!(v, "snot");
1033 vec![]
1034 }
1035 };
1036 let s = unsafe { String::from_utf8_unchecked(res.clone()) };
1037 println!("{s}");
1038 let v2: Value = from_slice(&mut res).expect("generated bad json");
1039 assert_eq!(v, v2);
1040 }
1041}