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