1use alloc::{borrow::Cow, string::String};
2use core::fmt;
3
4use serde::{ser, ser::Serialize};
5use serde_derive::{Deserialize, Serialize};
6use unicode_ident::is_xid_continue;
7
8use crate::{
9 error::{Error, Result},
10 extensions::Extensions,
11 options::Options,
12 parse::{is_ident_first_char, is_ident_raw_char, is_whitespace_char, LargeSInt, LargeUInt},
13};
14
15pub mod path_meta;
16
17mod raw;
18#[cfg(test)]
19mod tests;
20mod value;
21
22pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
30where
31 W: fmt::Write,
32 T: ?Sized + Serialize,
33{
34 Options::default().to_writer(writer, value)
35}
36
37pub fn to_writer_pretty<W, T>(writer: W, value: &T, config: PrettyConfig) -> Result<()>
42where
43 W: fmt::Write,
44 T: ?Sized + Serialize,
45{
46 Options::default().to_writer_pretty(writer, value, config)
47}
48
49pub fn to_string<T>(value: &T) -> Result<String>
54where
55 T: ?Sized + Serialize,
56{
57 Options::default().to_string(value)
58}
59
60pub fn to_string_pretty<T>(value: &T, config: PrettyConfig) -> Result<String>
62where
63 T: ?Sized + Serialize,
64{
65 Options::default().to_string_pretty(value, config)
66}
67
68struct Pretty {
70 indent: usize,
71}
72
73#[allow(clippy::struct_excessive_bools)]
86#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
87#[serde(default)]
88#[non_exhaustive]
89pub struct PrettyConfig {
90 pub depth_limit: usize,
92 pub new_line: Cow<'static, str>,
94 pub indentor: Cow<'static, str>,
96 pub separator: Cow<'static, str>,
98 pub struct_names: bool,
100 pub separate_tuple_members: bool,
102 pub enumerate_arrays: bool,
104 pub extensions: Extensions,
107 pub compact_arrays: bool,
110 pub escape_strings: bool,
113 pub compact_structs: bool,
116 pub compact_maps: bool,
119 pub number_suffixes: bool,
121 pub path_meta: Option<path_meta::Field>,
123}
124
125impl PrettyConfig {
126 #[must_use]
128 pub fn new() -> Self {
129 Self::default()
130 }
131
132 #[must_use]
139 pub fn depth_limit(mut self, depth_limit: usize) -> Self {
140 self.depth_limit = depth_limit;
141
142 self
143 }
144
145 #[must_use]
149 pub fn new_line(mut self, new_line: impl Into<Cow<'static, str>>) -> Self {
150 self.new_line = new_line.into();
151
152 self
153 }
154
155 #[must_use]
159 pub fn indentor(mut self, indentor: impl Into<Cow<'static, str>>) -> Self {
160 self.indentor = indentor.into();
161
162 self
163 }
164
165 #[must_use]
169 pub fn separator(mut self, separator: impl Into<Cow<'static, str>>) -> Self {
170 self.separator = separator.into();
171
172 self
173 }
174
175 #[must_use]
181 pub fn struct_names(mut self, struct_names: bool) -> Self {
182 self.struct_names = struct_names;
183
184 self
185 }
186
187 #[must_use]
194 pub fn separate_tuple_members(mut self, separate_tuple_members: bool) -> Self {
195 self.separate_tuple_members = separate_tuple_members;
196
197 self
198 }
199
200 #[must_use]
205 pub fn enumerate_arrays(mut self, enumerate_arrays: bool) -> Self {
206 self.enumerate_arrays = enumerate_arrays;
207
208 self
209 }
210
211 #[must_use]
230 pub fn compact_arrays(mut self, compact_arrays: bool) -> Self {
231 self.compact_arrays = compact_arrays;
232
233 self
234 }
235
236 #[must_use]
240 pub fn extensions(mut self, extensions: Extensions) -> Self {
241 self.extensions = extensions;
242
243 self
244 }
245
246 #[must_use]
263 pub fn escape_strings(mut self, escape_strings: bool) -> Self {
264 self.escape_strings = escape_strings;
265
266 self
267 }
268
269 #[must_use]
288 pub fn compact_structs(mut self, compact_structs: bool) -> Self {
289 self.compact_structs = compact_structs;
290
291 self
292 }
293
294 #[must_use]
314 pub fn compact_maps(mut self, compact_maps: bool) -> Self {
315 self.compact_maps = compact_maps;
316
317 self
318 }
319
320 #[must_use]
346 pub fn number_suffixes(mut self, number_suffixes: bool) -> Self {
347 self.number_suffixes = number_suffixes;
348
349 self
350 }
351}
352
353impl Default for PrettyConfig {
354 fn default() -> Self {
355 PrettyConfig {
356 depth_limit: usize::MAX,
357 new_line: if cfg!(not(target_os = "windows")) {
358 Cow::Borrowed("\n")
359 } else {
360 Cow::Borrowed("\r\n") },
362 indentor: Cow::Borrowed(" "),
363 separator: Cow::Borrowed(" "),
364 struct_names: false,
365 separate_tuple_members: false,
366 enumerate_arrays: false,
367 extensions: Extensions::empty(),
368 compact_arrays: false,
369 escape_strings: true,
370 compact_structs: false,
371 compact_maps: false,
372 number_suffixes: false,
373 path_meta: None,
374 }
375 }
376}
377
378pub struct Serializer<W: fmt::Write> {
383 output: W,
384 pretty: Option<(PrettyConfig, Pretty)>,
385 default_extensions: Extensions,
386 is_empty: Option<bool>,
387 newtype_variant: bool,
388 recursion_limit: Option<usize>,
389 implicit_some_depth: usize,
391}
392
393fn indent<W: fmt::Write>(output: &mut W, config: &PrettyConfig, pretty: &Pretty) -> fmt::Result {
394 if pretty.indent <= config.depth_limit {
395 for _ in 0..pretty.indent {
396 output.write_str(&config.indentor)?;
397 }
398 }
399 Ok(())
400}
401
402impl<W: fmt::Write> Serializer<W> {
403 pub fn new(writer: W, config: Option<PrettyConfig>) -> Result<Self> {
408 Self::with_options(writer, config, &Options::default())
409 }
410
411 pub fn with_options(
416 mut writer: W,
417 config: Option<PrettyConfig>,
418 options: &Options,
419 ) -> Result<Self> {
420 if let Some(conf) = &config {
421 if !conf.new_line.chars().all(is_whitespace_char) {
422 return Err(Error::Message(String::from(
423 "Invalid non-whitespace `PrettyConfig::new_line`",
424 )));
425 }
426 if !conf.indentor.chars().all(is_whitespace_char) {
427 return Err(Error::Message(String::from(
428 "Invalid non-whitespace `PrettyConfig::indentor`",
429 )));
430 }
431 if !conf.separator.chars().all(is_whitespace_char) {
432 return Err(Error::Message(String::from(
433 "Invalid non-whitespace `PrettyConfig::separator`",
434 )));
435 }
436
437 let non_default_extensions = !options.default_extensions;
438
439 for (extension_name, _) in (non_default_extensions & conf.extensions).iter_names() {
440 write!(writer, "#![enable({})]", extension_name.to_lowercase())?;
441 writer.write_str(&conf.new_line)?;
442 }
443 };
444 Ok(Serializer {
445 output: writer,
446 pretty: config.map(|conf| (conf, Pretty { indent: 0 })),
447 default_extensions: options.default_extensions,
448 is_empty: None,
449 newtype_variant: false,
450 recursion_limit: options.recursion_limit,
451 implicit_some_depth: 0,
452 })
453 }
454
455 #[inline]
457 pub fn into_inner(self) -> W {
458 self.output
459 }
460
461 fn separate_tuple_members(&self) -> bool {
462 self.pretty
463 .as_ref()
464 .map_or(false, |(ref config, _)| config.separate_tuple_members)
465 }
466
467 fn compact_arrays(&self) -> bool {
468 self.pretty
469 .as_ref()
470 .map_or(false, |(ref config, _)| config.compact_arrays)
471 }
472
473 fn compact_structs(&self) -> bool {
474 self.pretty
475 .as_ref()
476 .map_or(false, |(ref config, _)| config.compact_structs)
477 }
478
479 fn compact_maps(&self) -> bool {
480 self.pretty
481 .as_ref()
482 .map_or(false, |(ref config, _)| config.compact_maps)
483 }
484
485 fn number_suffixes(&self) -> bool {
486 self.pretty
487 .as_ref()
488 .map_or(false, |(ref config, _)| config.number_suffixes)
489 }
490
491 fn extensions(&self) -> Extensions {
492 self.default_extensions
493 | self
494 .pretty
495 .as_ref()
496 .map_or(Extensions::empty(), |(ref config, _)| config.extensions)
497 }
498
499 fn escape_strings(&self) -> bool {
500 self.pretty
501 .as_ref()
502 .map_or(true, |(ref config, _)| config.escape_strings)
503 }
504
505 fn start_indent(&mut self) -> Result<()> {
506 if let Some((ref config, ref mut pretty)) = self.pretty {
507 pretty.indent += 1;
508 if pretty.indent <= config.depth_limit {
509 let is_empty = self.is_empty.unwrap_or(false);
510
511 if !is_empty {
512 self.output.write_str(&config.new_line)?;
513 }
514 }
515 }
516 Ok(())
517 }
518
519 fn indent(&mut self) -> fmt::Result {
520 if let Some((ref config, ref pretty)) = self.pretty {
521 indent(&mut self.output, config, pretty)?;
522 }
523 Ok(())
524 }
525
526 fn end_indent(&mut self) -> fmt::Result {
527 if let Some((ref config, ref mut pretty)) = self.pretty {
528 if pretty.indent <= config.depth_limit {
529 let is_empty = self.is_empty.unwrap_or(false);
530
531 if !is_empty {
532 for _ in 1..pretty.indent {
533 self.output.write_str(&config.indentor)?;
534 }
535 }
536 }
537 pretty.indent -= 1;
538
539 self.is_empty = None;
540 }
541 Ok(())
542 }
543
544 fn serialize_escaped_str(&mut self, value: &str) -> fmt::Result {
545 self.output.write_char('"')?;
546 let mut scalar = [0u8; 4];
547 for c in value.chars().flat_map(char::escape_debug) {
548 self.output.write_str(c.encode_utf8(&mut scalar))?;
549 }
550 self.output.write_char('"')?;
551 Ok(())
552 }
553
554 fn serialize_unescaped_or_raw_str(&mut self, value: &str) -> fmt::Result {
555 if value.contains('"') || value.contains('\\') {
556 let (_, num_consecutive_hashes) =
557 value.chars().fold((0, 0), |(count, max), c| match c {
558 '#' => (count + 1, max.max(count + 1)),
559 _ => (0_usize, max),
560 });
561 let hashes: String = "#".repeat(num_consecutive_hashes + 1);
562 self.output.write_char('r')?;
563 self.output.write_str(&hashes)?;
564 self.output.write_char('"')?;
565 self.output.write_str(value)?;
566 self.output.write_char('"')?;
567 self.output.write_str(&hashes)?;
568 } else {
569 self.output.write_char('"')?;
570 self.output.write_str(value)?;
571 self.output.write_char('"')?;
572 }
573 Ok(())
574 }
575
576 fn serialize_escaped_byte_str(&mut self, value: &[u8]) -> fmt::Result {
577 self.output.write_str("b\"")?;
578 for c in value.iter().flat_map(|c| core::ascii::escape_default(*c)) {
579 self.output.write_char(char::from(c))?;
580 }
581 self.output.write_char('"')?;
582 Ok(())
583 }
584
585 fn serialize_unescaped_or_raw_byte_str(&mut self, value: &str) -> fmt::Result {
586 if value.contains('"') || value.contains('\\') {
587 let (_, num_consecutive_hashes) =
588 value.chars().fold((0, 0), |(count, max), c| match c {
589 '#' => (count + 1, max.max(count + 1)),
590 _ => (0_usize, max),
591 });
592 let hashes: String = "#".repeat(num_consecutive_hashes + 1);
593 self.output.write_str("br")?;
594 self.output.write_str(&hashes)?;
595 self.output.write_char('"')?;
596 self.output.write_str(value)?;
597 self.output.write_char('"')?;
598 self.output.write_str(&hashes)?;
599 } else {
600 self.output.write_str("b\"")?;
601 self.output.write_str(value)?;
602 self.output.write_char('"')?;
603 }
604 Ok(())
605 }
606
607 fn serialize_sint(&mut self, value: impl Into<LargeSInt>, suffix: &str) -> Result<()> {
608 write!(self.output, "{}", value.into())?;
610
611 if self.number_suffixes() {
612 write!(self.output, "{}", suffix)?;
613 }
614
615 Ok(())
616 }
617
618 fn serialize_uint(&mut self, value: impl Into<LargeUInt>, suffix: &str) -> Result<()> {
619 write!(self.output, "{}", value.into())?;
621
622 if self.number_suffixes() {
623 write!(self.output, "{}", suffix)?;
624 }
625
626 Ok(())
627 }
628
629 fn write_identifier(&mut self, name: &str) -> Result<()> {
630 self.validate_identifier(name)?;
631 let mut chars = name.chars();
632 if !chars.next().map_or(false, is_ident_first_char)
633 || !chars.all(is_xid_continue)
634 || [
635 "true", "false", "Some", "None", "inf", "inff32", "inff64", "NaN", "NaNf32",
636 "NaNf64",
637 ]
638 .contains(&name)
639 {
640 self.output.write_str("r#")?;
641 }
642 self.output.write_str(name)?;
643 Ok(())
644 }
645
646 #[allow(clippy::unused_self)]
647 fn validate_identifier(&self, name: &str) -> Result<()> {
648 if name.is_empty() || !name.chars().all(is_ident_raw_char) {
649 return Err(Error::InvalidIdentifier(name.into()));
650 }
651 Ok(())
652 }
653
654 fn struct_names(&self) -> bool {
658 self.extensions()
659 .contains(Extensions::EXPLICIT_STRUCT_NAMES)
660 || self
661 .pretty
662 .as_ref()
663 .map_or(false, |(pc, _)| pc.struct_names)
664 }
665}
666
667macro_rules! guard_recursion {
668 ($self:expr => $expr:expr) => {{
669 if let Some(limit) = &mut $self.recursion_limit {
670 if let Some(new_limit) = limit.checked_sub(1) {
671 *limit = new_limit;
672 } else {
673 return Err(Error::ExceededRecursionLimit);
674 }
675 }
676
677 let result = $expr;
678
679 if let Some(limit) = &mut $self.recursion_limit {
680 *limit = limit.saturating_add(1);
681 }
682
683 result
684 }};
685}
686
687impl<'a, W: fmt::Write> ser::Serializer for &'a mut Serializer<W> {
688 type Error = Error;
689 type Ok = ();
690 type SerializeMap = Compound<'a, W>;
691 type SerializeSeq = Compound<'a, W>;
692 type SerializeStruct = Compound<'a, W>;
693 type SerializeStructVariant = Compound<'a, W>;
694 type SerializeTuple = Compound<'a, W>;
695 type SerializeTupleStruct = Compound<'a, W>;
696 type SerializeTupleVariant = Compound<'a, W>;
697
698 fn serialize_bool(self, v: bool) -> Result<()> {
699 self.output.write_str(if v { "true" } else { "false" })?;
700 Ok(())
701 }
702
703 fn serialize_i8(self, v: i8) -> Result<()> {
704 self.serialize_sint(v, "i8")
705 }
706
707 fn serialize_i16(self, v: i16) -> Result<()> {
708 self.serialize_sint(v, "i16")
709 }
710
711 fn serialize_i32(self, v: i32) -> Result<()> {
712 self.serialize_sint(v, "i32")
713 }
714
715 fn serialize_i64(self, v: i64) -> Result<()> {
716 self.serialize_sint(v, "i64")
717 }
718
719 #[cfg(feature = "integer128")]
720 fn serialize_i128(self, v: i128) -> Result<()> {
721 self.serialize_sint(v, "i128")
722 }
723
724 fn serialize_u8(self, v: u8) -> Result<()> {
725 self.serialize_uint(v, "u8")
726 }
727
728 fn serialize_u16(self, v: u16) -> Result<()> {
729 self.serialize_uint(v, "u16")
730 }
731
732 fn serialize_u32(self, v: u32) -> Result<()> {
733 self.serialize_uint(v, "u32")
734 }
735
736 fn serialize_u64(self, v: u64) -> Result<()> {
737 self.serialize_uint(v, "u64")
738 }
739
740 #[cfg(feature = "integer128")]
741 fn serialize_u128(self, v: u128) -> Result<()> {
742 self.serialize_uint(v, "u128")
743 }
744
745 fn serialize_f32(self, v: f32) -> Result<()> {
746 if v.is_nan() && v.is_sign_negative() {
747 write!(self.output, "-")?;
748 }
749
750 write!(self.output, "{}", v)?;
751
752 if v % 1. == 0.0 {
755 write!(self.output, ".0")?;
756 }
757
758 if self.number_suffixes() {
759 write!(self.output, "f32")?;
760 }
761
762 Ok(())
763 }
764
765 fn serialize_f64(self, v: f64) -> Result<()> {
766 if v.is_nan() && v.is_sign_negative() {
767 write!(self.output, "-")?;
768 }
769
770 write!(self.output, "{}", v)?;
771
772 if v % 1. == 0.0 {
775 write!(self.output, ".0")?;
776 }
777
778 if self.number_suffixes() {
779 write!(self.output, "f64")?;
780 }
781
782 Ok(())
783 }
784
785 fn serialize_char(self, v: char) -> Result<()> {
786 self.output.write_char('\'')?;
787 if v == '\\' || v == '\'' {
788 self.output.write_char('\\')?;
789 }
790 write!(self.output, "{}", v)?;
791 self.output.write_char('\'')?;
792 Ok(())
793 }
794
795 fn serialize_str(self, v: &str) -> Result<()> {
796 if self.escape_strings() {
797 self.serialize_escaped_str(v)?;
798 } else {
799 self.serialize_unescaped_or_raw_str(v)?;
800 }
801
802 Ok(())
803 }
804
805 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
806 if !self.escape_strings() {
808 if let Ok(v) = core::str::from_utf8(v) {
809 return self
810 .serialize_unescaped_or_raw_byte_str(v)
811 .map_err(Error::from);
812 }
813 }
814
815 self.serialize_escaped_byte_str(v)?;
816
817 Ok(())
818 }
819
820 fn serialize_none(self) -> Result<()> {
821 let implicit_some_depth = self.implicit_some_depth;
823 self.implicit_some_depth = 0;
824
825 for _ in 0..implicit_some_depth {
826 self.output.write_str("Some(")?;
827 }
828 self.output.write_str("None")?;
829 for _ in 0..implicit_some_depth {
830 self.output.write_char(')')?;
831 }
832
833 Ok(())
834 }
835
836 fn serialize_some<T>(self, value: &T) -> Result<()>
837 where
838 T: ?Sized + Serialize,
839 {
840 let implicit_some = self.extensions().contains(Extensions::IMPLICIT_SOME);
841 if implicit_some {
842 self.implicit_some_depth += 1;
843 } else {
844 self.newtype_variant = self
845 .extensions()
846 .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
847 self.output.write_str("Some(")?;
848 }
849 guard_recursion! { self => value.serialize(&mut *self)? };
850 if implicit_some {
851 self.implicit_some_depth = 0;
852 } else {
853 self.output.write_char(')')?;
854 self.newtype_variant = false;
855 }
856
857 Ok(())
858 }
859
860 fn serialize_unit(self) -> Result<()> {
861 if !self.newtype_variant {
862 self.output.write_str("()")?;
863 }
864
865 Ok(())
866 }
867
868 fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
869 if self.struct_names() && !self.newtype_variant {
870 self.write_identifier(name)?;
871
872 Ok(())
873 } else {
874 self.validate_identifier(name)?;
875 self.serialize_unit()
876 }
877 }
878
879 fn serialize_unit_variant(
880 self,
881 name: &'static str,
882 _variant_index: u32,
883 variant: &'static str,
884 ) -> Result<()> {
885 self.validate_identifier(name)?;
886 self.write_identifier(variant)?;
887
888 Ok(())
889 }
890
891 fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
892 where
893 T: ?Sized + Serialize,
894 {
895 if name == crate::value::raw::RAW_VALUE_TOKEN {
896 let implicit_some_depth = self.implicit_some_depth;
897 self.implicit_some_depth = 0;
898
899 for _ in 0..implicit_some_depth {
900 self.output.write_str("Some(")?;
901 }
902
903 guard_recursion! { self => value.serialize(raw::Serializer::new(self)) }?;
904
905 for _ in 0..implicit_some_depth {
906 self.output.write_char(')')?;
907 }
908
909 return Ok(());
910 }
911
912 if self.extensions().contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
913 self.newtype_variant = false;
914
915 self.validate_identifier(name)?;
916
917 return guard_recursion! { self => value.serialize(&mut *self) };
918 }
919
920 if self.struct_names() {
921 self.write_identifier(name)?;
922 } else {
923 self.validate_identifier(name)?;
924 }
925
926 self.implicit_some_depth = 0;
927
928 self.output.write_char('(')?;
929 guard_recursion! { self => value.serialize(&mut *self)? };
930 self.output.write_char(')')?;
931
932 Ok(())
933 }
934
935 fn serialize_newtype_variant<T>(
936 self,
937 name: &'static str,
938 _variant_index: u32,
939 variant: &'static str,
940 value: &T,
941 ) -> Result<()>
942 where
943 T: ?Sized + Serialize,
944 {
945 self.validate_identifier(name)?;
946 self.write_identifier(variant)?;
947 self.output.write_char('(')?;
948
949 self.newtype_variant = self
950 .extensions()
951 .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
952 self.implicit_some_depth = 0;
953
954 guard_recursion! { self => value.serialize(&mut *self)? };
955
956 self.newtype_variant = false;
957
958 self.output.write_char(')')?;
959 Ok(())
960 }
961
962 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
963 self.newtype_variant = false;
964 self.implicit_some_depth = 0;
965
966 self.output.write_char('[')?;
967
968 if !self.compact_arrays() {
969 if let Some(len) = len {
970 self.is_empty = Some(len == 0);
971 }
972
973 self.start_indent()?;
974 }
975
976 Ok(Compound::new(self, false))
977 }
978
979 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
980 let old_newtype_variant = self.newtype_variant;
981 self.newtype_variant = false;
982 self.implicit_some_depth = 0;
983
984 if !old_newtype_variant {
985 self.output.write_char('(')?;
986 }
987
988 if self.separate_tuple_members() {
989 self.is_empty = Some(len == 0);
990
991 self.start_indent()?;
992 }
993
994 Ok(Compound::new(self, old_newtype_variant))
995 }
996
997 fn serialize_tuple_struct(
998 self,
999 name: &'static str,
1000 len: usize,
1001 ) -> Result<Self::SerializeTupleStruct> {
1002 if self.struct_names() && !self.newtype_variant {
1003 self.write_identifier(name)?;
1004 } else {
1005 self.validate_identifier(name)?;
1006 }
1007
1008 self.serialize_tuple(len)
1009 }
1010
1011 fn serialize_tuple_variant(
1012 self,
1013 name: &'static str,
1014 _variant_index: u32,
1015 variant: &'static str,
1016 len: usize,
1017 ) -> Result<Self::SerializeTupleVariant> {
1018 self.newtype_variant = false;
1019 self.implicit_some_depth = 0;
1020
1021 self.validate_identifier(name)?;
1022 self.write_identifier(variant)?;
1023 self.output.write_char('(')?;
1024
1025 if self.separate_tuple_members() {
1026 self.is_empty = Some(len == 0);
1027
1028 self.start_indent()?;
1029 }
1030
1031 Ok(Compound::new(self, false))
1032 }
1033
1034 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
1035 self.newtype_variant = false;
1036 self.implicit_some_depth = 0;
1037
1038 self.output.write_char('{')?;
1039
1040 if !self.compact_maps() {
1041 if let Some(len) = len {
1042 self.is_empty = Some(len == 0);
1043 }
1044
1045 self.start_indent()?;
1046 }
1047
1048 Ok(Compound::new(self, false))
1049 }
1050
1051 fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
1052 let old_newtype_variant = self.newtype_variant;
1053 self.newtype_variant = false;
1054 self.implicit_some_depth = 0;
1055
1056 if old_newtype_variant {
1057 self.validate_identifier(name)?;
1058 } else {
1059 if self.struct_names() {
1060 self.write_identifier(name)?;
1061 } else {
1062 self.validate_identifier(name)?;
1063 }
1064 self.output.write_char('(')?;
1065 }
1066
1067 if !self.compact_structs() {
1068 self.is_empty = Some(len == 0);
1069 self.start_indent()?;
1070 }
1071
1072 Ok(Compound::new(self, old_newtype_variant))
1073 }
1074
1075 fn serialize_struct_variant(
1076 self,
1077 name: &'static str,
1078 _variant_index: u32,
1079 variant: &'static str,
1080 len: usize,
1081 ) -> Result<Self::SerializeStructVariant> {
1082 self.newtype_variant = false;
1083 self.implicit_some_depth = 0;
1084
1085 self.validate_identifier(name)?;
1086 self.write_identifier(variant)?;
1087 self.output.write_char('(')?;
1088
1089 if !self.compact_structs() {
1090 self.is_empty = Some(len == 0);
1091 self.start_indent()?;
1092 }
1093
1094 Ok(Compound::new(self, false))
1095 }
1096}
1097
1098enum State {
1099 First,
1100 Rest,
1101}
1102
1103#[doc(hidden)]
1104pub struct Compound<'a, W: fmt::Write> {
1105 ser: &'a mut Serializer<W>,
1106 state: State,
1107 newtype_variant: bool,
1108 sequence_index: usize,
1109}
1110
1111impl<'a, W: fmt::Write> Compound<'a, W> {
1112 fn new(ser: &'a mut Serializer<W>, newtype_variant: bool) -> Self {
1113 Compound {
1114 ser,
1115 state: State::First,
1116 newtype_variant,
1117 sequence_index: 0,
1118 }
1119 }
1120}
1121
1122impl<'a, W: fmt::Write> Drop for Compound<'a, W> {
1123 fn drop(&mut self) {
1124 if let Some(limit) = &mut self.ser.recursion_limit {
1125 *limit = limit.saturating_add(1);
1126 }
1127 }
1128}
1129
1130impl<'a, W: fmt::Write> ser::SerializeSeq for Compound<'a, W> {
1131 type Error = Error;
1132 type Ok = ();
1133
1134 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1135 where
1136 T: ?Sized + Serialize,
1137 {
1138 if let State::First = self.state {
1139 self.state = State::Rest;
1140 } else {
1141 self.ser.output.write_char(',')?;
1142 if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1143 if pretty.indent <= config.depth_limit && !config.compact_arrays {
1144 self.ser.output.write_str(&config.new_line)?;
1145 } else {
1146 self.ser.output.write_str(&config.separator)?;
1147 }
1148 }
1149 }
1150
1151 if !self.ser.compact_arrays() {
1152 self.ser.indent()?;
1153 }
1154
1155 if let Some((ref mut config, ref mut pretty)) = self.ser.pretty {
1156 if pretty.indent <= config.depth_limit && config.enumerate_arrays {
1157 write!(self.ser.output, "/*[{}]*/ ", self.sequence_index)?;
1158 self.sequence_index += 1;
1159 }
1160 }
1161
1162 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1163
1164 Ok(())
1165 }
1166
1167 fn end(self) -> Result<()> {
1168 if let State::Rest = self.state {
1169 if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1170 if pretty.indent <= config.depth_limit && !config.compact_arrays {
1171 self.ser.output.write_char(',')?;
1172 self.ser.output.write_str(&config.new_line)?;
1173 }
1174 }
1175 }
1176
1177 if !self.ser.compact_arrays() {
1178 self.ser.end_indent()?;
1179 }
1180
1181 self.ser.output.write_char(']')?;
1183 Ok(())
1184 }
1185}
1186
1187impl<'a, W: fmt::Write> ser::SerializeTuple for Compound<'a, W> {
1188 type Error = Error;
1189 type Ok = ();
1190
1191 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1192 where
1193 T: ?Sized + Serialize,
1194 {
1195 if let State::First = self.state {
1196 self.state = State::Rest;
1197 } else {
1198 self.ser.output.write_char(',')?;
1199 if let Some((ref config, ref pretty)) = self.ser.pretty {
1200 if pretty.indent <= config.depth_limit && self.ser.separate_tuple_members() {
1201 self.ser.output.write_str(&config.new_line)?;
1202 } else {
1203 self.ser.output.write_str(&config.separator)?;
1204 }
1205 }
1206 }
1207
1208 if self.ser.separate_tuple_members() {
1209 self.ser.indent()?;
1210 }
1211
1212 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1213
1214 Ok(())
1215 }
1216
1217 fn end(self) -> Result<()> {
1218 if let State::Rest = self.state {
1219 if let Some((ref config, ref pretty)) = self.ser.pretty {
1220 if self.ser.separate_tuple_members() && pretty.indent <= config.depth_limit {
1221 self.ser.output.write_char(',')?;
1222 self.ser.output.write_str(&config.new_line)?;
1223 }
1224 }
1225 }
1226 if self.ser.separate_tuple_members() {
1227 self.ser.end_indent()?;
1228 }
1229
1230 if !self.newtype_variant {
1231 self.ser.output.write_char(')')?;
1232 }
1233
1234 Ok(())
1235 }
1236}
1237
1238impl<'a, W: fmt::Write> ser::SerializeTupleStruct for Compound<'a, W> {
1240 type Error = Error;
1241 type Ok = ();
1242
1243 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1244 where
1245 T: ?Sized + Serialize,
1246 {
1247 ser::SerializeTuple::serialize_element(self, value)
1248 }
1249
1250 fn end(self) -> Result<()> {
1251 ser::SerializeTuple::end(self)
1252 }
1253}
1254
1255impl<'a, W: fmt::Write> ser::SerializeTupleVariant for Compound<'a, W> {
1256 type Error = Error;
1257 type Ok = ();
1258
1259 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1260 where
1261 T: ?Sized + Serialize,
1262 {
1263 ser::SerializeTuple::serialize_element(self, value)
1264 }
1265
1266 fn end(self) -> Result<()> {
1267 ser::SerializeTuple::end(self)
1268 }
1269}
1270
1271impl<'a, W: fmt::Write> ser::SerializeMap for Compound<'a, W> {
1272 type Error = Error;
1273 type Ok = ();
1274
1275 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
1276 where
1277 T: ?Sized + Serialize,
1278 {
1279 if let State::First = self.state {
1280 self.state = State::Rest;
1281 } else {
1282 self.ser.output.write_char(',')?;
1283
1284 if let Some((ref config, ref pretty)) = self.ser.pretty {
1285 if pretty.indent <= config.depth_limit && !config.compact_maps {
1286 self.ser.output.write_str(&config.new_line)?;
1287 } else {
1288 self.ser.output.write_str(&config.separator)?;
1289 }
1290 }
1291 }
1292
1293 if !self.ser.compact_maps() {
1294 self.ser.indent()?;
1295 }
1296
1297 guard_recursion! { self.ser => key.serialize(&mut *self.ser) }
1298 }
1299
1300 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
1301 where
1302 T: ?Sized + Serialize,
1303 {
1304 self.ser.output.write_char(':')?;
1305
1306 if let Some((ref config, _)) = self.ser.pretty {
1307 self.ser.output.write_str(&config.separator)?;
1308 }
1309
1310 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1311
1312 Ok(())
1313 }
1314
1315 fn end(self) -> Result<()> {
1316 if let State::Rest = self.state {
1317 if let Some((ref config, ref pretty)) = self.ser.pretty {
1318 if pretty.indent <= config.depth_limit && !config.compact_maps {
1319 self.ser.output.write_char(',')?;
1320 self.ser.output.write_str(&config.new_line)?;
1321 }
1322 }
1323 }
1324
1325 if !self.ser.compact_maps() {
1326 self.ser.end_indent()?;
1327 }
1328
1329 self.ser.output.write_char('}')?;
1331 Ok(())
1332 }
1333}
1334
1335impl<'a, W: fmt::Write> ser::SerializeStruct for Compound<'a, W> {
1336 type Error = Error;
1337 type Ok = ();
1338
1339 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1340 where
1341 T: ?Sized + Serialize,
1342 {
1343 let mut restore_field = self.ser.pretty.as_mut().and_then(|(config, _)| {
1344 config.path_meta.take().map(|mut field| {
1345 if let Some(fields) = field.fields_mut() {
1346 config.path_meta = fields.remove(key);
1347 }
1348 field
1349 })
1350 });
1351
1352 if let State::First = self.state {
1353 self.state = State::Rest;
1354 } else {
1355 self.ser.output.write_char(',')?;
1356
1357 if let Some((ref config, ref pretty)) = self.ser.pretty {
1358 if pretty.indent <= config.depth_limit && !config.compact_structs {
1359 self.ser.output.write_str(&config.new_line)?;
1360 } else {
1361 self.ser.output.write_str(&config.separator)?;
1362 }
1363 }
1364 }
1365
1366 if !self.ser.compact_structs() {
1367 if let Some((ref config, ref pretty)) = self.ser.pretty {
1368 indent(&mut self.ser.output, config, pretty)?;
1369
1370 if let Some(ref field) = config.path_meta {
1371 for doc_line in field.doc().lines() {
1372 self.ser.output.write_str("/// ")?;
1373 self.ser.output.write_str(doc_line)?;
1374 self.ser.output.write_char('\n')?;
1375 indent(&mut self.ser.output, config, pretty)?;
1376 }
1377 }
1378 }
1379 }
1380
1381 self.ser.write_identifier(key)?;
1382 self.ser.output.write_char(':')?;
1383
1384 if let Some((ref config, _)) = self.ser.pretty {
1385 self.ser.output.write_str(&config.separator)?;
1386 }
1387
1388 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1389
1390 if let Some((ref mut config, _)) = self.ser.pretty {
1391 core::mem::swap(&mut config.path_meta, &mut restore_field);
1392
1393 if let Some(ref mut field) = config.path_meta {
1394 if let Some(fields) = field.fields_mut() {
1395 if let Some(restore_field) = restore_field {
1396 fields.insert(key, restore_field);
1397 }
1398 }
1399 }
1400 };
1401
1402 Ok(())
1403 }
1404
1405 fn end(self) -> Result<()> {
1406 if let State::Rest = self.state {
1407 if let Some((ref config, ref pretty)) = self.ser.pretty {
1408 if pretty.indent <= config.depth_limit && !config.compact_structs {
1409 self.ser.output.write_char(',')?;
1410 self.ser.output.write_str(&config.new_line)?;
1411 }
1412 }
1413 }
1414
1415 if !self.ser.compact_structs() {
1416 self.ser.end_indent()?;
1417 }
1418
1419 if !self.newtype_variant {
1420 self.ser.output.write_char(')')?;
1421 }
1422
1423 Ok(())
1424 }
1425}
1426
1427impl<'a, W: fmt::Write> ser::SerializeStructVariant for Compound<'a, W> {
1428 type Error = Error;
1429 type Ok = ();
1430
1431 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1432 where
1433 T: ?Sized + Serialize,
1434 {
1435 ser::SerializeStruct::serialize_field(self, key, value)
1436 }
1437
1438 fn end(self) -> Result<()> {
1439 ser::SerializeStruct::end(self)
1440 }
1441}