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 pub compact_ranges: bool,
125}
126
127impl PrettyConfig {
128 #[must_use]
130 pub fn new() -> Self {
131 Self::default()
132 }
133
134 #[must_use]
141 pub fn depth_limit(mut self, depth_limit: usize) -> Self {
142 self.depth_limit = depth_limit;
143
144 self
145 }
146
147 #[must_use]
151 pub fn new_line(mut self, new_line: impl Into<Cow<'static, str>>) -> Self {
152 self.new_line = new_line.into();
153
154 self
155 }
156
157 #[must_use]
161 pub fn indentor(mut self, indentor: impl Into<Cow<'static, str>>) -> Self {
162 self.indentor = indentor.into();
163
164 self
165 }
166
167 #[must_use]
171 pub fn separator(mut self, separator: impl Into<Cow<'static, str>>) -> Self {
172 self.separator = separator.into();
173
174 self
175 }
176
177 #[must_use]
183 pub fn struct_names(mut self, struct_names: bool) -> Self {
184 self.struct_names = struct_names;
185
186 self
187 }
188
189 #[must_use]
196 pub fn separate_tuple_members(mut self, separate_tuple_members: bool) -> Self {
197 self.separate_tuple_members = separate_tuple_members;
198
199 self
200 }
201
202 #[must_use]
207 pub fn enumerate_arrays(mut self, enumerate_arrays: bool) -> Self {
208 self.enumerate_arrays = enumerate_arrays;
209
210 self
211 }
212
213 #[must_use]
232 pub fn compact_arrays(mut self, compact_arrays: bool) -> Self {
233 self.compact_arrays = compact_arrays;
234
235 self
236 }
237
238 #[must_use]
242 pub fn extensions(mut self, extensions: Extensions) -> Self {
243 self.extensions = extensions;
244
245 self
246 }
247
248 #[must_use]
265 pub fn escape_strings(mut self, escape_strings: bool) -> Self {
266 self.escape_strings = escape_strings;
267
268 self
269 }
270
271 #[must_use]
290 pub fn compact_structs(mut self, compact_structs: bool) -> Self {
291 self.compact_structs = compact_structs;
292
293 self
294 }
295
296 #[must_use]
316 pub fn compact_maps(mut self, compact_maps: bool) -> Self {
317 self.compact_maps = compact_maps;
318
319 self
320 }
321
322 #[must_use]
348 pub fn number_suffixes(mut self, number_suffixes: bool) -> Self {
349 self.number_suffixes = number_suffixes;
350
351 self
352 }
353
354 #[must_use]
382 pub fn compact_ranges(mut self, compact_ranges: bool) -> Self {
383 self.compact_ranges = compact_ranges;
384 self
385 }
386}
387
388impl Default for PrettyConfig {
389 fn default() -> Self {
390 PrettyConfig {
391 depth_limit: usize::MAX,
392 new_line: if cfg!(not(target_os = "windows")) {
393 Cow::Borrowed("\n")
394 } else {
395 Cow::Borrowed("\r\n") },
397 indentor: Cow::Borrowed(" "),
398 separator: Cow::Borrowed(" "),
399 struct_names: false,
400 separate_tuple_members: false,
401 enumerate_arrays: false,
402 extensions: Extensions::empty(),
403 compact_arrays: false,
404 escape_strings: true,
405 compact_structs: false,
406 compact_maps: false,
407 number_suffixes: false,
408 path_meta: None,
409 compact_ranges: false,
410 }
411 }
412}
413
414pub struct Serializer<W: fmt::Write> {
419 output: W,
420 pretty: Option<(PrettyConfig, Pretty)>,
421 default_extensions: Extensions,
422 is_empty: Option<bool>,
423 newtype_variant: bool,
424 recursion_limit: Option<usize>,
425 implicit_some_depth: usize,
427}
428
429fn indent<W: fmt::Write>(output: &mut W, config: &PrettyConfig, pretty: &Pretty) -> fmt::Result {
430 if pretty.indent <= config.depth_limit {
431 for _ in 0..pretty.indent {
432 output.write_str(&config.indentor)?;
433 }
434 }
435 Ok(())
436}
437
438impl<W: fmt::Write> Serializer<W> {
439 pub fn new(writer: W, config: Option<PrettyConfig>) -> Result<Self> {
444 Self::with_options(writer, config, &Options::default())
445 }
446
447 pub fn with_options(
452 mut writer: W,
453 config: Option<PrettyConfig>,
454 options: &Options,
455 ) -> Result<Self> {
456 if let Some(conf) = &config {
457 if !conf.new_line.chars().all(is_whitespace_char) {
458 return Err(Error::Message(String::from(
459 "Invalid non-whitespace `PrettyConfig::new_line`",
460 )));
461 }
462 if !conf.indentor.chars().all(is_whitespace_char) {
463 return Err(Error::Message(String::from(
464 "Invalid non-whitespace `PrettyConfig::indentor`",
465 )));
466 }
467 if !conf.separator.chars().all(is_whitespace_char) {
468 return Err(Error::Message(String::from(
469 "Invalid non-whitespace `PrettyConfig::separator`",
470 )));
471 }
472
473 let non_default_extensions = !options.default_extensions;
474
475 for (extension_name, _) in (non_default_extensions & conf.extensions).iter_names() {
476 write!(writer, "#![enable({})]", extension_name.to_lowercase())?;
477 writer.write_str(&conf.new_line)?;
478 }
479 };
480 Ok(Serializer {
481 output: writer,
482 pretty: config.map(|conf| (conf, Pretty { indent: 0 })),
483 default_extensions: options.default_extensions,
484 is_empty: None,
485 newtype_variant: false,
486 recursion_limit: options.recursion_limit,
487 implicit_some_depth: 0,
488 })
489 }
490
491 #[inline]
493 pub fn into_inner(self) -> W {
494 self.output
495 }
496
497 fn separate_tuple_members(&self) -> bool {
498 self.pretty
499 .as_ref()
500 .map_or(false, |(ref config, _)| config.separate_tuple_members)
501 }
502
503 fn compact_arrays(&self) -> bool {
504 self.pretty
505 .as_ref()
506 .map_or(false, |(ref config, _)| config.compact_arrays)
507 }
508
509 fn compact_structs(&self) -> bool {
510 self.pretty
511 .as_ref()
512 .map_or(false, |(ref config, _)| config.compact_structs)
513 }
514
515 fn compact_maps(&self) -> bool {
516 self.pretty
517 .as_ref()
518 .map_or(false, |(ref config, _)| config.compact_maps)
519 }
520
521 fn number_suffixes(&self) -> bool {
522 self.pretty
523 .as_ref()
524 .map_or(false, |(ref config, _)| config.number_suffixes)
525 }
526
527 fn compact_ranges(&self) -> bool {
528 self.pretty
529 .as_ref()
530 .map_or(false, |(ref config, _)| config.compact_ranges)
531 }
532
533 fn extensions(&self) -> Extensions {
534 self.default_extensions
535 | self
536 .pretty
537 .as_ref()
538 .map_or(Extensions::empty(), |(ref config, _)| config.extensions)
539 }
540
541 fn escape_strings(&self) -> bool {
542 self.pretty
543 .as_ref()
544 .map_or(true, |(ref config, _)| config.escape_strings)
545 }
546
547 fn start_indent(&mut self) -> Result<()> {
548 if let Some((ref config, ref mut pretty)) = self.pretty {
549 pretty.indent += 1;
550 if pretty.indent <= config.depth_limit {
551 let is_empty = self.is_empty.unwrap_or(false);
552
553 if !is_empty {
554 self.output.write_str(&config.new_line)?;
555 }
556 }
557 }
558 Ok(())
559 }
560
561 fn indent(&mut self) -> fmt::Result {
562 if let Some((ref config, ref pretty)) = self.pretty {
563 indent(&mut self.output, config, pretty)?;
564 }
565 Ok(())
566 }
567
568 fn end_indent(&mut self) -> fmt::Result {
569 if let Some((ref config, ref mut pretty)) = self.pretty {
570 if pretty.indent <= config.depth_limit {
571 let is_empty = self.is_empty.unwrap_or(false);
572
573 if !is_empty {
574 for _ in 1..pretty.indent {
575 self.output.write_str(&config.indentor)?;
576 }
577 }
578 }
579 pretty.indent -= 1;
580
581 self.is_empty = None;
582 }
583 Ok(())
584 }
585
586 fn serialize_escaped_str(&mut self, value: &str) -> fmt::Result {
587 self.output.write_char('"')?;
588 let mut scalar = [0u8; 4];
589 for c in value.chars().flat_map(char::escape_debug) {
590 self.output.write_str(c.encode_utf8(&mut scalar))?;
591 }
592 self.output.write_char('"')?;
593 Ok(())
594 }
595
596 fn serialize_unescaped_or_raw_str(&mut self, value: &str) -> fmt::Result {
597 if value.contains('"') || value.contains('\\') {
598 let (_, num_consecutive_hashes) =
599 value.chars().fold((0, 0), |(count, max), c| match c {
600 '#' => (count + 1, max.max(count + 1)),
601 _ => (0_usize, max),
602 });
603 let hashes: String = "#".repeat(num_consecutive_hashes + 1);
604 self.output.write_char('r')?;
605 self.output.write_str(&hashes)?;
606 self.output.write_char('"')?;
607 self.output.write_str(value)?;
608 self.output.write_char('"')?;
609 self.output.write_str(&hashes)?;
610 } else {
611 self.output.write_char('"')?;
612 self.output.write_str(value)?;
613 self.output.write_char('"')?;
614 }
615 Ok(())
616 }
617
618 fn serialize_escaped_byte_str(&mut self, value: &[u8]) -> fmt::Result {
619 self.output.write_str("b\"")?;
620 for c in value.iter().flat_map(|c| core::ascii::escape_default(*c)) {
621 self.output.write_char(char::from(c))?;
622 }
623 self.output.write_char('"')?;
624 Ok(())
625 }
626
627 fn serialize_unescaped_or_raw_byte_str(&mut self, value: &str) -> fmt::Result {
628 if value.contains('"') || value.contains('\\') {
629 let (_, num_consecutive_hashes) =
630 value.chars().fold((0, 0), |(count, max), c| match c {
631 '#' => (count + 1, max.max(count + 1)),
632 _ => (0_usize, max),
633 });
634 let hashes: String = "#".repeat(num_consecutive_hashes + 1);
635 self.output.write_str("br")?;
636 self.output.write_str(&hashes)?;
637 self.output.write_char('"')?;
638 self.output.write_str(value)?;
639 self.output.write_char('"')?;
640 self.output.write_str(&hashes)?;
641 } else {
642 self.output.write_str("b\"")?;
643 self.output.write_str(value)?;
644 self.output.write_char('"')?;
645 }
646 Ok(())
647 }
648
649 fn serialize_sint(&mut self, value: impl Into<LargeSInt>, suffix: &str) -> Result<()> {
650 write!(self.output, "{}", value.into())?;
652
653 if self.number_suffixes() {
654 write!(self.output, "{}", suffix)?;
655 }
656
657 Ok(())
658 }
659
660 fn serialize_uint(&mut self, value: impl Into<LargeUInt>, suffix: &str) -> Result<()> {
661 write!(self.output, "{}", value.into())?;
663
664 if self.number_suffixes() {
665 write!(self.output, "{}", suffix)?;
666 }
667
668 Ok(())
669 }
670
671 fn write_identifier(&mut self, name: &str) -> Result<()> {
672 self.validate_identifier(name)?;
673 let mut chars = name.chars();
674 if !chars.next().map_or(false, is_ident_first_char)
675 || !chars.all(is_xid_continue)
676 || [
677 "true", "false", "Some", "None", "inf", "inff32", "inff64", "NaN", "NaNf32",
678 "NaNf64",
679 ]
680 .contains(&name)
681 {
682 self.output.write_str("r#")?;
683 }
684 self.output.write_str(name)?;
685 Ok(())
686 }
687
688 #[allow(clippy::unused_self)]
689 fn validate_identifier(&self, name: &str) -> Result<()> {
690 if name.is_empty() || !name.chars().all(is_ident_raw_char) {
691 return Err(Error::InvalidIdentifier(name.into()));
692 }
693 Ok(())
694 }
695
696 fn struct_names(&self) -> bool {
700 self.extensions()
701 .contains(Extensions::EXPLICIT_STRUCT_NAMES)
702 || self
703 .pretty
704 .as_ref()
705 .map_or(false, |(pc, _)| pc.struct_names)
706 }
707}
708
709macro_rules! guard_recursion {
710 ($self:expr => $expr:expr) => {{
711 if let Some(limit) = &mut $self.recursion_limit {
712 if let Some(new_limit) = limit.checked_sub(1) {
713 *limit = new_limit;
714 } else {
715 return Err(Error::ExceededRecursionLimit);
716 }
717 }
718
719 let result = $expr;
720
721 if let Some(limit) = &mut $self.recursion_limit {
722 *limit = limit.saturating_add(1);
723 }
724
725 result
726 }};
727}
728
729impl<'a, W: fmt::Write> ser::Serializer for &'a mut Serializer<W> {
730 type Error = Error;
731 type Ok = ();
732 type SerializeMap = Compound<'a, W>;
733 type SerializeSeq = Compound<'a, W>;
734 type SerializeStruct = Compound<'a, W>;
735 type SerializeStructVariant = Compound<'a, W>;
736 type SerializeTuple = Compound<'a, W>;
737 type SerializeTupleStruct = Compound<'a, W>;
738 type SerializeTupleVariant = Compound<'a, W>;
739
740 fn serialize_bool(self, v: bool) -> Result<()> {
741 self.output.write_str(if v { "true" } else { "false" })?;
742 Ok(())
743 }
744
745 fn serialize_i8(self, v: i8) -> Result<()> {
746 self.serialize_sint(v, "i8")
747 }
748
749 fn serialize_i16(self, v: i16) -> Result<()> {
750 self.serialize_sint(v, "i16")
751 }
752
753 fn serialize_i32(self, v: i32) -> Result<()> {
754 self.serialize_sint(v, "i32")
755 }
756
757 fn serialize_i64(self, v: i64) -> Result<()> {
758 self.serialize_sint(v, "i64")
759 }
760
761 #[cfg(feature = "integer128")]
762 fn serialize_i128(self, v: i128) -> Result<()> {
763 self.serialize_sint(v, "i128")
764 }
765
766 fn serialize_u8(self, v: u8) -> Result<()> {
767 self.serialize_uint(v, "u8")
768 }
769
770 fn serialize_u16(self, v: u16) -> Result<()> {
771 self.serialize_uint(v, "u16")
772 }
773
774 fn serialize_u32(self, v: u32) -> Result<()> {
775 self.serialize_uint(v, "u32")
776 }
777
778 fn serialize_u64(self, v: u64) -> Result<()> {
779 self.serialize_uint(v, "u64")
780 }
781
782 #[cfg(feature = "integer128")]
783 fn serialize_u128(self, v: u128) -> Result<()> {
784 self.serialize_uint(v, "u128")
785 }
786
787 fn serialize_f32(self, v: f32) -> Result<()> {
788 if v.is_nan() && v.is_sign_negative() {
789 write!(self.output, "-")?;
790 }
791
792 write!(self.output, "{:?}", v)?;
797
798 if self.number_suffixes() {
799 write!(self.output, "f32")?;
800 }
801
802 Ok(())
803 }
804
805 fn serialize_f64(self, v: f64) -> Result<()> {
806 if v.is_nan() && v.is_sign_negative() {
807 write!(self.output, "-")?;
808 }
809
810 write!(self.output, "{:?}", v)?;
815
816 if self.number_suffixes() {
817 write!(self.output, "f64")?;
818 }
819
820 Ok(())
821 }
822
823 fn serialize_char(self, v: char) -> Result<()> {
824 self.output.write_char('\'')?;
825 if v == '\\' || v == '\'' {
826 self.output.write_char('\\')?;
827 }
828 write!(self.output, "{}", v)?;
829 self.output.write_char('\'')?;
830 Ok(())
831 }
832
833 fn serialize_str(self, v: &str) -> Result<()> {
834 if self.escape_strings() {
835 self.serialize_escaped_str(v)?;
836 } else {
837 self.serialize_unescaped_or_raw_str(v)?;
838 }
839
840 Ok(())
841 }
842
843 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
844 if !self.escape_strings() {
846 if let Ok(v) = core::str::from_utf8(v) {
847 return self
848 .serialize_unescaped_or_raw_byte_str(v)
849 .map_err(Error::from);
850 }
851 }
852
853 self.serialize_escaped_byte_str(v)?;
854
855 Ok(())
856 }
857
858 fn serialize_none(self) -> Result<()> {
859 let implicit_some_depth = self.implicit_some_depth;
861 self.implicit_some_depth = 0;
862
863 for _ in 0..implicit_some_depth {
864 self.output.write_str("Some(")?;
865 }
866 self.output.write_str("None")?;
867 for _ in 0..implicit_some_depth {
868 self.output.write_char(')')?;
869 }
870
871 Ok(())
872 }
873
874 fn serialize_some<T>(self, value: &T) -> Result<()>
875 where
876 T: ?Sized + Serialize,
877 {
878 let implicit_some = self.extensions().contains(Extensions::IMPLICIT_SOME);
879 if implicit_some {
880 self.implicit_some_depth += 1;
881 } else {
882 self.newtype_variant = self
883 .extensions()
884 .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
885 self.output.write_str("Some(")?;
886 }
887 guard_recursion! { self => value.serialize(&mut *self)? };
888 if implicit_some {
889 self.implicit_some_depth = 0;
890 } else {
891 self.output.write_char(')')?;
892 self.newtype_variant = false;
893 }
894
895 Ok(())
896 }
897
898 fn serialize_unit(self) -> Result<()> {
899 if !self.newtype_variant {
900 self.output.write_str("()")?;
901 }
902
903 Ok(())
904 }
905
906 fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
907 if self.compact_ranges() && name == "RangeFull" {
908 self.output.write_str("..")?;
909 return Ok(());
910 }
911
912 if self.struct_names() && !self.newtype_variant {
913 self.write_identifier(name)?;
914
915 Ok(())
916 } else {
917 self.validate_identifier(name)?;
918 self.serialize_unit()
919 }
920 }
921
922 fn serialize_unit_variant(
923 self,
924 name: &'static str,
925 _variant_index: u32,
926 variant: &'static str,
927 ) -> Result<()> {
928 self.validate_identifier(name)?;
929 self.write_identifier(variant)?;
930
931 Ok(())
932 }
933
934 fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
935 where
936 T: ?Sized + Serialize,
937 {
938 if name == crate::value::raw::RAW_VALUE_TOKEN {
939 let implicit_some_depth = self.implicit_some_depth;
940 self.implicit_some_depth = 0;
941
942 for _ in 0..implicit_some_depth {
943 self.output.write_str("Some(")?;
944 }
945
946 guard_recursion! { self => value.serialize(raw::Serializer::new(self)) }?;
947
948 for _ in 0..implicit_some_depth {
949 self.output.write_char(')')?;
950 }
951
952 return Ok(());
953 }
954
955 if self.extensions().contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
956 self.newtype_variant = false;
957
958 self.validate_identifier(name)?;
959
960 return guard_recursion! { self => value.serialize(&mut *self) };
961 }
962
963 if self.struct_names() {
964 self.write_identifier(name)?;
965 } else {
966 self.validate_identifier(name)?;
967 }
968
969 self.implicit_some_depth = 0;
970
971 self.output.write_char('(')?;
972 guard_recursion! { self => value.serialize(&mut *self)? };
973 self.output.write_char(')')?;
974
975 Ok(())
976 }
977
978 fn serialize_newtype_variant<T>(
979 self,
980 name: &'static str,
981 _variant_index: u32,
982 variant: &'static str,
983 value: &T,
984 ) -> Result<()>
985 where
986 T: ?Sized + Serialize,
987 {
988 self.validate_identifier(name)?;
989 self.write_identifier(variant)?;
990 self.output.write_char('(')?;
991
992 self.newtype_variant = self
993 .extensions()
994 .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
995 self.implicit_some_depth = 0;
996
997 guard_recursion! { self => value.serialize(&mut *self)? };
998
999 self.newtype_variant = false;
1000
1001 self.output.write_char(')')?;
1002 Ok(())
1003 }
1004
1005 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
1006 self.newtype_variant = false;
1007 self.implicit_some_depth = 0;
1008
1009 self.output.write_char('[')?;
1010
1011 if !self.compact_arrays() {
1012 if let Some(len) = len {
1013 self.is_empty = Some(len == 0);
1014 }
1015
1016 self.start_indent()?;
1017 }
1018
1019 Ok(Compound::new(self, false))
1020 }
1021
1022 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
1023 let old_newtype_variant = self.newtype_variant;
1024 self.newtype_variant = false;
1025 self.implicit_some_depth = 0;
1026
1027 if !old_newtype_variant {
1028 self.output.write_char('(')?;
1029 }
1030
1031 if self.separate_tuple_members() {
1032 self.is_empty = Some(len == 0);
1033
1034 self.start_indent()?;
1035 }
1036
1037 Ok(Compound::new(self, old_newtype_variant))
1038 }
1039
1040 fn serialize_tuple_struct(
1041 self,
1042 name: &'static str,
1043 len: usize,
1044 ) -> Result<Self::SerializeTupleStruct> {
1045 if self.struct_names() && !self.newtype_variant {
1046 self.write_identifier(name)?;
1047 } else {
1048 self.validate_identifier(name)?;
1049 }
1050
1051 self.serialize_tuple(len)
1052 }
1053
1054 fn serialize_tuple_variant(
1055 self,
1056 name: &'static str,
1057 _variant_index: u32,
1058 variant: &'static str,
1059 len: usize,
1060 ) -> Result<Self::SerializeTupleVariant> {
1061 self.newtype_variant = false;
1062 self.implicit_some_depth = 0;
1063
1064 self.validate_identifier(name)?;
1065 self.write_identifier(variant)?;
1066 self.output.write_char('(')?;
1067
1068 if self.separate_tuple_members() {
1069 self.is_empty = Some(len == 0);
1070
1071 self.start_indent()?;
1072 }
1073
1074 Ok(Compound::new(self, false))
1075 }
1076
1077 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
1078 self.newtype_variant = false;
1079 self.implicit_some_depth = 0;
1080
1081 self.output.write_char('{')?;
1082
1083 if !self.compact_maps() {
1084 if let Some(len) = len {
1085 self.is_empty = Some(len == 0);
1086 }
1087
1088 self.start_indent()?;
1089 }
1090
1091 Ok(Compound::new(self, false))
1092 }
1093
1094 fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
1095 let old_newtype_variant = self.newtype_variant;
1096 if self.compact_ranges()
1097 && ((len == 2 && (name == "Range" || name == "RangeInclusive"))
1098 || (len == 1
1099 && (name == "RangeFrom" || name == "RangeTo" || name == "RangeToInclusive")))
1100 {
1101 self.newtype_variant = false;
1102 self.implicit_some_depth = 0;
1103 return Ok(Compound::new_range(
1104 self,
1105 name,
1106 old_newtype_variant,
1107 if name == "RangeInclusive" {
1108 RangeKind::RangeInclusive
1109 } else if name == "RangeFrom" {
1110 RangeKind::RangeFrom
1111 } else if name == "RangeTo" {
1112 RangeKind::RangeTo
1113 } else if name == "RangeToInclusive" {
1114 RangeKind::RangeToInclusive
1115 } else {
1116 RangeKind::Range
1117 },
1118 ));
1119 }
1120
1121 self.newtype_variant = false;
1122 self.implicit_some_depth = 0;
1123
1124 if old_newtype_variant {
1125 self.validate_identifier(name)?;
1126 } else {
1127 if self.struct_names() {
1128 self.write_identifier(name)?;
1129 } else {
1130 self.validate_identifier(name)?;
1131 }
1132 self.output.write_char('(')?;
1133 }
1134
1135 if !self.compact_structs() {
1136 self.is_empty = Some(len == 0);
1137 self.start_indent()?;
1138 }
1139
1140 Ok(Compound::new(self, old_newtype_variant))
1141 }
1142
1143 fn serialize_struct_variant(
1144 self,
1145 name: &'static str,
1146 _variant_index: u32,
1147 variant: &'static str,
1148 len: usize,
1149 ) -> Result<Self::SerializeStructVariant> {
1150 self.newtype_variant = false;
1151 self.implicit_some_depth = 0;
1152
1153 self.validate_identifier(name)?;
1154 self.write_identifier(variant)?;
1155 self.output.write_char('(')?;
1156
1157 if !self.compact_structs() {
1158 self.is_empty = Some(len == 0);
1159 self.start_indent()?;
1160 }
1161
1162 Ok(Compound::new(self, false))
1163 }
1164}
1165
1166enum State {
1167 First,
1168 Rest,
1169}
1170
1171#[doc(hidden)]
1172pub struct Compound<'a, W: fmt::Write> {
1173 ser: &'a mut Serializer<W>,
1174 state: State,
1175 newtype_variant: bool,
1176 sequence_index: usize,
1177 range: Option<RangeCompound>,
1178}
1179
1180impl<'a, W: fmt::Write> Compound<'a, W> {
1181 fn new(ser: &'a mut Serializer<W>, newtype_variant: bool) -> Self {
1182 Compound {
1183 ser,
1184 state: State::First,
1185 newtype_variant,
1186 sequence_index: 0,
1187 range: None,
1188 }
1189 }
1190
1191 fn new_range(
1192 ser: &'a mut Serializer<W>,
1193 name: &'static str,
1194 newtype_variant: bool,
1195 kind: RangeKind,
1196 ) -> Self {
1197 Compound {
1198 ser,
1199 state: State::First,
1200 newtype_variant: false,
1201 sequence_index: 0,
1202 range: Some(RangeCompound::new(name, newtype_variant, kind)),
1203 }
1204 }
1205}
1206
1207enum RangeKind {
1208 Range,
1209 RangeInclusive,
1210 RangeFrom,
1211 RangeTo,
1212 RangeToInclusive,
1213}
1214
1215struct RangeCompound {
1216 name: &'static str,
1217 newtype_variant: bool,
1220 kind: RangeKind,
1221 first: Option<(&'static str, crate::value::Number)>,
1223 second: Option<(&'static str, crate::value::Number)>,
1224 fallback: bool,
1225}
1226
1227impl RangeCompound {
1228 fn new(name: &'static str, newtype_variant: bool, kind: RangeKind) -> Self {
1229 RangeCompound {
1230 name,
1231 newtype_variant,
1232 kind,
1233 first: None,
1234 second: None,
1235 fallback: false,
1236 }
1237 }
1238
1239 fn try_serialize_number<T>(value: &T) -> Option<crate::value::Number>
1242 where
1243 T: ?Sized + Serialize,
1244 {
1245 value.serialize(crate::value::NumberSerializer).ok()
1246 }
1247}
1248
1249impl<'a, W: fmt::Write> Drop for Compound<'a, W> {
1250 fn drop(&mut self) {
1251 if let Some(limit) = &mut self.ser.recursion_limit {
1252 *limit = limit.saturating_add(1);
1253 }
1254 }
1255}
1256
1257impl<'a, W: fmt::Write> ser::SerializeSeq for Compound<'a, W> {
1258 type Error = Error;
1259 type Ok = ();
1260
1261 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1262 where
1263 T: ?Sized + Serialize,
1264 {
1265 if let State::First = self.state {
1266 self.state = State::Rest;
1267 } else {
1268 self.ser.output.write_char(',')?;
1269 if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1270 if pretty.indent <= config.depth_limit && !config.compact_arrays {
1271 self.ser.output.write_str(&config.new_line)?;
1272 } else {
1273 self.ser.output.write_str(&config.separator)?;
1274 }
1275 }
1276 }
1277
1278 if !self.ser.compact_arrays() {
1279 self.ser.indent()?;
1280 }
1281
1282 if let Some((ref mut config, ref mut pretty)) = self.ser.pretty {
1283 if pretty.indent <= config.depth_limit && config.enumerate_arrays {
1284 write!(self.ser.output, "/*[{}]*/ ", self.sequence_index)?;
1285 self.sequence_index += 1;
1286 }
1287 }
1288
1289 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1290
1291 Ok(())
1292 }
1293
1294 fn end(self) -> Result<()> {
1295 if let State::Rest = self.state {
1296 if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1297 if pretty.indent <= config.depth_limit && !config.compact_arrays {
1298 self.ser.output.write_char(',')?;
1299 self.ser.output.write_str(&config.new_line)?;
1300 }
1301 }
1302 }
1303
1304 if !self.ser.compact_arrays() {
1305 self.ser.end_indent()?;
1306 }
1307
1308 self.ser.output.write_char(']')?;
1310 Ok(())
1311 }
1312}
1313
1314impl<'a, W: fmt::Write> ser::SerializeTuple for Compound<'a, W> {
1315 type Error = Error;
1316 type Ok = ();
1317
1318 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1319 where
1320 T: ?Sized + Serialize,
1321 {
1322 if let State::First = self.state {
1323 self.state = State::Rest;
1324 } else {
1325 self.ser.output.write_char(',')?;
1326 if let Some((ref config, ref pretty)) = self.ser.pretty {
1327 if pretty.indent <= config.depth_limit && self.ser.separate_tuple_members() {
1328 self.ser.output.write_str(&config.new_line)?;
1329 } else {
1330 self.ser.output.write_str(&config.separator)?;
1331 }
1332 }
1333 }
1334
1335 if self.ser.separate_tuple_members() {
1336 self.ser.indent()?;
1337 }
1338
1339 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1340
1341 Ok(())
1342 }
1343
1344 fn end(self) -> Result<()> {
1345 if let State::Rest = self.state {
1346 if let Some((ref config, ref pretty)) = self.ser.pretty {
1347 if self.ser.separate_tuple_members() && pretty.indent <= config.depth_limit {
1348 self.ser.output.write_char(',')?;
1349 self.ser.output.write_str(&config.new_line)?;
1350 }
1351 }
1352 }
1353 if self.ser.separate_tuple_members() {
1354 self.ser.end_indent()?;
1355 }
1356
1357 if !self.newtype_variant {
1358 self.ser.output.write_char(')')?;
1359 }
1360
1361 Ok(())
1362 }
1363}
1364
1365impl<'a, W: fmt::Write> ser::SerializeTupleStruct for Compound<'a, W> {
1367 type Error = Error;
1368 type Ok = ();
1369
1370 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1371 where
1372 T: ?Sized + Serialize,
1373 {
1374 ser::SerializeTuple::serialize_element(self, value)
1375 }
1376
1377 fn end(self) -> Result<()> {
1378 ser::SerializeTuple::end(self)
1379 }
1380}
1381
1382impl<'a, W: fmt::Write> ser::SerializeTupleVariant for Compound<'a, W> {
1383 type Error = Error;
1384 type Ok = ();
1385
1386 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1387 where
1388 T: ?Sized + Serialize,
1389 {
1390 ser::SerializeTuple::serialize_element(self, value)
1391 }
1392
1393 fn end(self) -> Result<()> {
1394 ser::SerializeTuple::end(self)
1395 }
1396}
1397
1398impl<'a, W: fmt::Write> ser::SerializeMap for Compound<'a, W> {
1399 type Error = Error;
1400 type Ok = ();
1401
1402 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
1403 where
1404 T: ?Sized + Serialize,
1405 {
1406 if let State::First = self.state {
1407 self.state = State::Rest;
1408 } else {
1409 self.ser.output.write_char(',')?;
1410
1411 if let Some((ref config, ref pretty)) = self.ser.pretty {
1412 if pretty.indent <= config.depth_limit && !config.compact_maps {
1413 self.ser.output.write_str(&config.new_line)?;
1414 } else {
1415 self.ser.output.write_str(&config.separator)?;
1416 }
1417 }
1418 }
1419
1420 if !self.ser.compact_maps() {
1421 self.ser.indent()?;
1422 }
1423
1424 guard_recursion! { self.ser => key.serialize(&mut *self.ser) }
1425 }
1426
1427 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
1428 where
1429 T: ?Sized + Serialize,
1430 {
1431 self.ser.output.write_char(':')?;
1432
1433 if let Some((ref config, _)) = self.ser.pretty {
1434 self.ser.output.write_str(&config.separator)?;
1435 }
1436
1437 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1438
1439 Ok(())
1440 }
1441
1442 fn end(self) -> Result<()> {
1443 if let State::Rest = self.state {
1444 if let Some((ref config, ref pretty)) = self.ser.pretty {
1445 if pretty.indent <= config.depth_limit && !config.compact_maps {
1446 self.ser.output.write_char(',')?;
1447 self.ser.output.write_str(&config.new_line)?;
1448 }
1449 }
1450 }
1451
1452 if !self.ser.compact_maps() {
1453 self.ser.end_indent()?;
1454 }
1455
1456 self.ser.output.write_char('}')?;
1458 Ok(())
1459 }
1460}
1461
1462impl<'a, W: fmt::Write> ser::SerializeStruct for Compound<'a, W> {
1463 type Error = Error;
1464 type Ok = ();
1465
1466 #[allow(clippy::too_many_lines)]
1467 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1468 where
1469 T: ?Sized + Serialize,
1470 {
1471 if let Some(ref mut range) = self.range {
1472 if !range.fallback {
1473 match RangeCompound::try_serialize_number(value) {
1474 Some(s) => {
1475 let expected_key = match range.kind {
1478 RangeKind::RangeTo | RangeKind::RangeToInclusive => {
1479 if range.first.is_none() {
1480 "end"
1481 } else {
1482 ""
1483 }
1484 }
1485 _ => {
1486 if range.first.is_none() {
1487 "start"
1488 } else {
1489 "end"
1490 }
1491 }
1492 };
1493
1494 let max_fields = match range.kind {
1495 RangeKind::RangeFrom
1496 | RangeKind::RangeTo
1497 | RangeKind::RangeToInclusive => 1,
1498 RangeKind::Range | RangeKind::RangeInclusive => 2,
1499 };
1500
1501 if key != expected_key
1502 || (range.first.is_some() && max_fields < 2)
1503 || range.second.is_some()
1504 {
1505 range.fallback = true;
1506 } else if range.first.is_none() {
1507 range.first = Some((key, s));
1510 } else {
1511 range.second = Some((key, s));
1512 }
1513
1514 if !range.fallback {
1515 return Ok(());
1516 }
1517 }
1518 None => {
1519 range.fallback = true;
1520 }
1521 }
1522
1523 if range.newtype_variant {
1525 self.newtype_variant = true;
1526 } else {
1527 if self.ser.struct_names() {
1528 self.ser.write_identifier(range.name)?;
1529 }
1530 self.ser.output.write_char('(')?;
1531 }
1532 if !self.ser.compact_structs() {
1533 self.ser.is_empty = Some(false);
1534 self.ser.start_indent()?;
1535 }
1536
1537 let buffered: [Option<(&'static str, crate::value::Number)>; 2] =
1539 [range.first.take(), range.second.take()];
1540
1541 for (bkey, bval) in buffered.into_iter().flatten() {
1542 ser::SerializeStruct::serialize_field(self, bkey, &bval)?;
1543 }
1544 }
1546 }
1547
1548 let mut restore_field = self.ser.pretty.as_mut().and_then(|(config, _)| {
1549 config.path_meta.take().map(|mut field| {
1550 if let Some(fields) = field.fields_mut() {
1551 config.path_meta = fields.remove(key);
1552 }
1553 field
1554 })
1555 });
1556
1557 if let State::First = self.state {
1558 self.state = State::Rest;
1559 } else {
1560 self.ser.output.write_char(',')?;
1561
1562 if let Some((ref config, ref pretty)) = self.ser.pretty {
1563 if pretty.indent <= config.depth_limit && !config.compact_structs {
1564 self.ser.output.write_str(&config.new_line)?;
1565 } else {
1566 self.ser.output.write_str(&config.separator)?;
1567 }
1568 }
1569 }
1570
1571 if !self.ser.compact_structs() {
1572 if let Some((ref config, ref pretty)) = self.ser.pretty {
1573 indent(&mut self.ser.output, config, pretty)?;
1574
1575 if let Some(ref field) = config.path_meta {
1576 for doc_line in field.doc().lines() {
1577 self.ser.output.write_str("/// ")?;
1578 self.ser.output.write_str(doc_line)?;
1579 self.ser.output.write_str(&config.new_line)?;
1580 indent(&mut self.ser.output, config, pretty)?;
1581 }
1582 }
1583 }
1584 }
1585
1586 self.ser.write_identifier(key)?;
1587 self.ser.output.write_char(':')?;
1588
1589 if let Some((ref config, _)) = self.ser.pretty {
1590 self.ser.output.write_str(&config.separator)?;
1591 }
1592
1593 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1594
1595 if let Some((ref mut config, _)) = self.ser.pretty {
1596 core::mem::swap(&mut config.path_meta, &mut restore_field);
1597
1598 if let Some(ref mut field) = config.path_meta {
1599 if let Some(fields) = field.fields_mut() {
1600 if let Some(restore_field) = restore_field {
1601 fields.insert(key, restore_field);
1602 }
1603 }
1604 }
1605 };
1606
1607 Ok(())
1608 }
1609
1610 fn end(mut self) -> Result<()> {
1611 if let Some(ref mut range) = self.range {
1612 if !range.fallback {
1613 let sep = match range.kind {
1615 RangeKind::RangeInclusive | RangeKind::RangeToInclusive => "..=",
1616 _ => "..",
1617 };
1618
1619 match range.kind {
1620 RangeKind::RangeFrom => {
1621 if let Some((_, start)) = range.first.take() {
1622 start.serialize(&mut *self.ser)?;
1623 }
1624 self.ser.output.write_str("..")?;
1625 }
1626 RangeKind::RangeTo | RangeKind::RangeToInclusive => {
1627 self.ser.output.write_str(sep)?;
1628 if let Some((_, end)) = range.first.take() {
1629 end.serialize(&mut *self.ser)?;
1630 }
1631 }
1632 RangeKind::Range | RangeKind::RangeInclusive => {
1633 if let Some((_, start)) = range.first.take() {
1634 start.serialize(&mut *self.ser)?;
1635 }
1636 self.ser.output.write_str(sep)?;
1637 if let Some((_, end)) = range.second.take() {
1638 end.serialize(&mut *self.ser)?;
1639 }
1640 }
1641 }
1642 return Ok(());
1643 }
1644 }
1646
1647 if let State::Rest = self.state {
1648 if let Some((ref config, ref pretty)) = self.ser.pretty {
1649 if pretty.indent <= config.depth_limit && !config.compact_structs {
1650 self.ser.output.write_char(',')?;
1651 self.ser.output.write_str(&config.new_line)?;
1652 }
1653 }
1654 }
1655
1656 if !self.ser.compact_structs() {
1657 self.ser.end_indent()?;
1658 }
1659
1660 if !self.newtype_variant {
1661 self.ser.output.write_char(')')?;
1662 }
1663
1664 Ok(())
1665 }
1666}
1667
1668impl<'a, W: fmt::Write> ser::SerializeStructVariant for Compound<'a, W> {
1669 type Error = Error;
1670 type Ok = ();
1671
1672 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1673 where
1674 T: ?Sized + Serialize,
1675 {
1676 ser::SerializeStruct::serialize_field(self, key, value)
1677 }
1678
1679 fn end(self) -> Result<()> {
1680 ser::SerializeStruct::end(self)
1681 }
1682}