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)?;
793
794 if v % 1. == 0.0 {
797 write!(self.output, ".0")?;
798 }
799
800 if self.number_suffixes() {
801 write!(self.output, "f32")?;
802 }
803
804 Ok(())
805 }
806
807 fn serialize_f64(self, v: f64) -> Result<()> {
808 if v.is_nan() && v.is_sign_negative() {
809 write!(self.output, "-")?;
810 }
811
812 write!(self.output, "{}", v)?;
813
814 if v % 1. == 0.0 {
817 write!(self.output, ".0")?;
818 }
819
820 if self.number_suffixes() {
821 write!(self.output, "f64")?;
822 }
823
824 Ok(())
825 }
826
827 fn serialize_char(self, v: char) -> Result<()> {
828 self.output.write_char('\'')?;
829 if v == '\\' || v == '\'' {
830 self.output.write_char('\\')?;
831 }
832 write!(self.output, "{}", v)?;
833 self.output.write_char('\'')?;
834 Ok(())
835 }
836
837 fn serialize_str(self, v: &str) -> Result<()> {
838 if self.escape_strings() {
839 self.serialize_escaped_str(v)?;
840 } else {
841 self.serialize_unescaped_or_raw_str(v)?;
842 }
843
844 Ok(())
845 }
846
847 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
848 if !self.escape_strings() {
850 if let Ok(v) = core::str::from_utf8(v) {
851 return self
852 .serialize_unescaped_or_raw_byte_str(v)
853 .map_err(Error::from);
854 }
855 }
856
857 self.serialize_escaped_byte_str(v)?;
858
859 Ok(())
860 }
861
862 fn serialize_none(self) -> Result<()> {
863 let implicit_some_depth = self.implicit_some_depth;
865 self.implicit_some_depth = 0;
866
867 for _ in 0..implicit_some_depth {
868 self.output.write_str("Some(")?;
869 }
870 self.output.write_str("None")?;
871 for _ in 0..implicit_some_depth {
872 self.output.write_char(')')?;
873 }
874
875 Ok(())
876 }
877
878 fn serialize_some<T>(self, value: &T) -> Result<()>
879 where
880 T: ?Sized + Serialize,
881 {
882 let implicit_some = self.extensions().contains(Extensions::IMPLICIT_SOME);
883 if implicit_some {
884 self.implicit_some_depth += 1;
885 } else {
886 self.newtype_variant = self
887 .extensions()
888 .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
889 self.output.write_str("Some(")?;
890 }
891 guard_recursion! { self => value.serialize(&mut *self)? };
892 if implicit_some {
893 self.implicit_some_depth = 0;
894 } else {
895 self.output.write_char(')')?;
896 self.newtype_variant = false;
897 }
898
899 Ok(())
900 }
901
902 fn serialize_unit(self) -> Result<()> {
903 if !self.newtype_variant {
904 self.output.write_str("()")?;
905 }
906
907 Ok(())
908 }
909
910 fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
911 if self.compact_ranges() && name == "RangeFull" {
912 self.output.write_str("..")?;
913 return Ok(());
914 }
915
916 if self.struct_names() && !self.newtype_variant {
917 self.write_identifier(name)?;
918
919 Ok(())
920 } else {
921 self.validate_identifier(name)?;
922 self.serialize_unit()
923 }
924 }
925
926 fn serialize_unit_variant(
927 self,
928 name: &'static str,
929 _variant_index: u32,
930 variant: &'static str,
931 ) -> Result<()> {
932 self.validate_identifier(name)?;
933 self.write_identifier(variant)?;
934
935 Ok(())
936 }
937
938 fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
939 where
940 T: ?Sized + Serialize,
941 {
942 if name == crate::value::raw::RAW_VALUE_TOKEN {
943 let implicit_some_depth = self.implicit_some_depth;
944 self.implicit_some_depth = 0;
945
946 for _ in 0..implicit_some_depth {
947 self.output.write_str("Some(")?;
948 }
949
950 guard_recursion! { self => value.serialize(raw::Serializer::new(self)) }?;
951
952 for _ in 0..implicit_some_depth {
953 self.output.write_char(')')?;
954 }
955
956 return Ok(());
957 }
958
959 if self.extensions().contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
960 self.newtype_variant = false;
961
962 self.validate_identifier(name)?;
963
964 return guard_recursion! { self => value.serialize(&mut *self) };
965 }
966
967 if self.struct_names() {
968 self.write_identifier(name)?;
969 } else {
970 self.validate_identifier(name)?;
971 }
972
973 self.implicit_some_depth = 0;
974
975 self.output.write_char('(')?;
976 guard_recursion! { self => value.serialize(&mut *self)? };
977 self.output.write_char(')')?;
978
979 Ok(())
980 }
981
982 fn serialize_newtype_variant<T>(
983 self,
984 name: &'static str,
985 _variant_index: u32,
986 variant: &'static str,
987 value: &T,
988 ) -> Result<()>
989 where
990 T: ?Sized + Serialize,
991 {
992 self.validate_identifier(name)?;
993 self.write_identifier(variant)?;
994 self.output.write_char('(')?;
995
996 self.newtype_variant = self
997 .extensions()
998 .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
999 self.implicit_some_depth = 0;
1000
1001 guard_recursion! { self => value.serialize(&mut *self)? };
1002
1003 self.newtype_variant = false;
1004
1005 self.output.write_char(')')?;
1006 Ok(())
1007 }
1008
1009 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
1010 self.newtype_variant = false;
1011 self.implicit_some_depth = 0;
1012
1013 self.output.write_char('[')?;
1014
1015 if !self.compact_arrays() {
1016 if let Some(len) = len {
1017 self.is_empty = Some(len == 0);
1018 }
1019
1020 self.start_indent()?;
1021 }
1022
1023 Ok(Compound::new(self, false))
1024 }
1025
1026 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
1027 let old_newtype_variant = self.newtype_variant;
1028 self.newtype_variant = false;
1029 self.implicit_some_depth = 0;
1030
1031 if !old_newtype_variant {
1032 self.output.write_char('(')?;
1033 }
1034
1035 if self.separate_tuple_members() {
1036 self.is_empty = Some(len == 0);
1037
1038 self.start_indent()?;
1039 }
1040
1041 Ok(Compound::new(self, old_newtype_variant))
1042 }
1043
1044 fn serialize_tuple_struct(
1045 self,
1046 name: &'static str,
1047 len: usize,
1048 ) -> Result<Self::SerializeTupleStruct> {
1049 if self.struct_names() && !self.newtype_variant {
1050 self.write_identifier(name)?;
1051 } else {
1052 self.validate_identifier(name)?;
1053 }
1054
1055 self.serialize_tuple(len)
1056 }
1057
1058 fn serialize_tuple_variant(
1059 self,
1060 name: &'static str,
1061 _variant_index: u32,
1062 variant: &'static str,
1063 len: usize,
1064 ) -> Result<Self::SerializeTupleVariant> {
1065 self.newtype_variant = false;
1066 self.implicit_some_depth = 0;
1067
1068 self.validate_identifier(name)?;
1069 self.write_identifier(variant)?;
1070 self.output.write_char('(')?;
1071
1072 if self.separate_tuple_members() {
1073 self.is_empty = Some(len == 0);
1074
1075 self.start_indent()?;
1076 }
1077
1078 Ok(Compound::new(self, false))
1079 }
1080
1081 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
1082 self.newtype_variant = false;
1083 self.implicit_some_depth = 0;
1084
1085 self.output.write_char('{')?;
1086
1087 if !self.compact_maps() {
1088 if let Some(len) = len {
1089 self.is_empty = Some(len == 0);
1090 }
1091
1092 self.start_indent()?;
1093 }
1094
1095 Ok(Compound::new(self, false))
1096 }
1097
1098 fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
1099 let old_newtype_variant = self.newtype_variant;
1100 if self.compact_ranges()
1101 && ((len == 2 && (name == "Range" || name == "RangeInclusive"))
1102 || (len == 1
1103 && (name == "RangeFrom" || name == "RangeTo" || name == "RangeToInclusive")))
1104 {
1105 self.newtype_variant = false;
1106 self.implicit_some_depth = 0;
1107 return Ok(Compound::new_range(
1108 self,
1109 if name == "RangeInclusive" {
1110 RangeKind::RangeInclusive
1111 } else if name == "RangeFrom" {
1112 RangeKind::RangeFrom
1113 } else if name == "RangeTo" {
1114 RangeKind::RangeTo
1115 } else if name == "RangeToInclusive" {
1116 RangeKind::RangeToInclusive
1117 } else {
1118 RangeKind::Range
1119 },
1120 ));
1121 }
1122
1123 self.newtype_variant = false;
1124 self.implicit_some_depth = 0;
1125
1126 if old_newtype_variant {
1127 self.validate_identifier(name)?;
1128 } else {
1129 if self.struct_names() {
1130 self.write_identifier(name)?;
1131 } else {
1132 self.validate_identifier(name)?;
1133 }
1134 self.output.write_char('(')?;
1135 }
1136
1137 if !self.compact_structs() {
1138 self.is_empty = Some(len == 0);
1139 self.start_indent()?;
1140 }
1141
1142 Ok(Compound::new(self, old_newtype_variant))
1143 }
1144
1145 fn serialize_struct_variant(
1146 self,
1147 name: &'static str,
1148 _variant_index: u32,
1149 variant: &'static str,
1150 len: usize,
1151 ) -> Result<Self::SerializeStructVariant> {
1152 self.newtype_variant = false;
1153 self.implicit_some_depth = 0;
1154
1155 self.validate_identifier(name)?;
1156 self.write_identifier(variant)?;
1157 self.output.write_char('(')?;
1158
1159 if !self.compact_structs() {
1160 self.is_empty = Some(len == 0);
1161 self.start_indent()?;
1162 }
1163
1164 Ok(Compound::new(self, false))
1165 }
1166}
1167
1168enum State {
1169 First,
1170 Rest,
1171}
1172
1173#[doc(hidden)]
1174pub struct Compound<'a, W: fmt::Write> {
1175 ser: &'a mut Serializer<W>,
1176 state: State,
1177 newtype_variant: bool,
1178 sequence_index: usize,
1179 range: Option<RangeCompound>,
1180}
1181
1182impl<'a, W: fmt::Write> Compound<'a, W> {
1183 fn new(ser: &'a mut Serializer<W>, newtype_variant: bool) -> Self {
1184 Compound {
1185 ser,
1186 state: State::First,
1187 newtype_variant,
1188 sequence_index: 0,
1189 range: None,
1190 }
1191 }
1192
1193 fn new_range(ser: &'a mut Serializer<W>, kind: RangeKind) -> Self {
1194 Compound {
1195 ser,
1196 state: State::First,
1197 newtype_variant: false,
1198 sequence_index: 0,
1199 range: Some(RangeCompound::new(kind)),
1200 }
1201 }
1202}
1203
1204enum RangeKind {
1205 Range,
1206 RangeInclusive,
1207 RangeFrom,
1208 RangeTo,
1209 RangeToInclusive,
1210}
1211
1212struct RangeCompound {
1213 kind: RangeKind,
1214 first: Option<(&'static str, crate::value::Number)>,
1216 second: Option<(&'static str, crate::value::Number)>,
1217 fallback: bool,
1218}
1219
1220impl RangeCompound {
1221 fn new(kind: RangeKind) -> Self {
1222 RangeCompound {
1223 kind,
1224 first: None,
1225 second: None,
1226 fallback: false,
1227 }
1228 }
1229
1230 fn try_serialize_number<T>(value: &T) -> Option<crate::value::Number>
1233 where
1234 T: ?Sized + Serialize,
1235 {
1236 value.serialize(crate::value::NumberSerializer).ok()
1237 }
1238}
1239
1240impl<'a, W: fmt::Write> Drop for Compound<'a, W> {
1241 fn drop(&mut self) {
1242 if let Some(limit) = &mut self.ser.recursion_limit {
1243 *limit = limit.saturating_add(1);
1244 }
1245 }
1246}
1247
1248impl<'a, W: fmt::Write> ser::SerializeSeq for Compound<'a, W> {
1249 type Error = Error;
1250 type Ok = ();
1251
1252 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1253 where
1254 T: ?Sized + Serialize,
1255 {
1256 if let State::First = self.state {
1257 self.state = State::Rest;
1258 } else {
1259 self.ser.output.write_char(',')?;
1260 if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1261 if pretty.indent <= config.depth_limit && !config.compact_arrays {
1262 self.ser.output.write_str(&config.new_line)?;
1263 } else {
1264 self.ser.output.write_str(&config.separator)?;
1265 }
1266 }
1267 }
1268
1269 if !self.ser.compact_arrays() {
1270 self.ser.indent()?;
1271 }
1272
1273 if let Some((ref mut config, ref mut pretty)) = self.ser.pretty {
1274 if pretty.indent <= config.depth_limit && config.enumerate_arrays {
1275 write!(self.ser.output, "/*[{}]*/ ", self.sequence_index)?;
1276 self.sequence_index += 1;
1277 }
1278 }
1279
1280 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1281
1282 Ok(())
1283 }
1284
1285 fn end(self) -> Result<()> {
1286 if let State::Rest = self.state {
1287 if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1288 if pretty.indent <= config.depth_limit && !config.compact_arrays {
1289 self.ser.output.write_char(',')?;
1290 self.ser.output.write_str(&config.new_line)?;
1291 }
1292 }
1293 }
1294
1295 if !self.ser.compact_arrays() {
1296 self.ser.end_indent()?;
1297 }
1298
1299 self.ser.output.write_char(']')?;
1301 Ok(())
1302 }
1303}
1304
1305impl<'a, W: fmt::Write> ser::SerializeTuple for Compound<'a, W> {
1306 type Error = Error;
1307 type Ok = ();
1308
1309 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1310 where
1311 T: ?Sized + Serialize,
1312 {
1313 if let State::First = self.state {
1314 self.state = State::Rest;
1315 } else {
1316 self.ser.output.write_char(',')?;
1317 if let Some((ref config, ref pretty)) = self.ser.pretty {
1318 if pretty.indent <= config.depth_limit && self.ser.separate_tuple_members() {
1319 self.ser.output.write_str(&config.new_line)?;
1320 } else {
1321 self.ser.output.write_str(&config.separator)?;
1322 }
1323 }
1324 }
1325
1326 if self.ser.separate_tuple_members() {
1327 self.ser.indent()?;
1328 }
1329
1330 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1331
1332 Ok(())
1333 }
1334
1335 fn end(self) -> Result<()> {
1336 if let State::Rest = self.state {
1337 if let Some((ref config, ref pretty)) = self.ser.pretty {
1338 if self.ser.separate_tuple_members() && pretty.indent <= config.depth_limit {
1339 self.ser.output.write_char(',')?;
1340 self.ser.output.write_str(&config.new_line)?;
1341 }
1342 }
1343 }
1344 if self.ser.separate_tuple_members() {
1345 self.ser.end_indent()?;
1346 }
1347
1348 if !self.newtype_variant {
1349 self.ser.output.write_char(')')?;
1350 }
1351
1352 Ok(())
1353 }
1354}
1355
1356impl<'a, W: fmt::Write> ser::SerializeTupleStruct for Compound<'a, W> {
1358 type Error = Error;
1359 type Ok = ();
1360
1361 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1362 where
1363 T: ?Sized + Serialize,
1364 {
1365 ser::SerializeTuple::serialize_element(self, value)
1366 }
1367
1368 fn end(self) -> Result<()> {
1369 ser::SerializeTuple::end(self)
1370 }
1371}
1372
1373impl<'a, W: fmt::Write> ser::SerializeTupleVariant for Compound<'a, W> {
1374 type Error = Error;
1375 type Ok = ();
1376
1377 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1378 where
1379 T: ?Sized + Serialize,
1380 {
1381 ser::SerializeTuple::serialize_element(self, value)
1382 }
1383
1384 fn end(self) -> Result<()> {
1385 ser::SerializeTuple::end(self)
1386 }
1387}
1388
1389impl<'a, W: fmt::Write> ser::SerializeMap for Compound<'a, W> {
1390 type Error = Error;
1391 type Ok = ();
1392
1393 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
1394 where
1395 T: ?Sized + Serialize,
1396 {
1397 if let State::First = self.state {
1398 self.state = State::Rest;
1399 } else {
1400 self.ser.output.write_char(',')?;
1401
1402 if let Some((ref config, ref pretty)) = self.ser.pretty {
1403 if pretty.indent <= config.depth_limit && !config.compact_maps {
1404 self.ser.output.write_str(&config.new_line)?;
1405 } else {
1406 self.ser.output.write_str(&config.separator)?;
1407 }
1408 }
1409 }
1410
1411 if !self.ser.compact_maps() {
1412 self.ser.indent()?;
1413 }
1414
1415 guard_recursion! { self.ser => key.serialize(&mut *self.ser) }
1416 }
1417
1418 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
1419 where
1420 T: ?Sized + Serialize,
1421 {
1422 self.ser.output.write_char(':')?;
1423
1424 if let Some((ref config, _)) = self.ser.pretty {
1425 self.ser.output.write_str(&config.separator)?;
1426 }
1427
1428 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1429
1430 Ok(())
1431 }
1432
1433 fn end(self) -> Result<()> {
1434 if let State::Rest = self.state {
1435 if let Some((ref config, ref pretty)) = self.ser.pretty {
1436 if pretty.indent <= config.depth_limit && !config.compact_maps {
1437 self.ser.output.write_char(',')?;
1438 self.ser.output.write_str(&config.new_line)?;
1439 }
1440 }
1441 }
1442
1443 if !self.ser.compact_maps() {
1444 self.ser.end_indent()?;
1445 }
1446
1447 self.ser.output.write_char('}')?;
1449 Ok(())
1450 }
1451}
1452
1453impl<'a, W: fmt::Write> ser::SerializeStruct for Compound<'a, W> {
1454 type Error = Error;
1455 type Ok = ();
1456
1457 #[allow(clippy::too_many_lines)]
1458 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1459 where
1460 T: ?Sized + Serialize,
1461 {
1462 if let Some(ref mut range) = self.range {
1463 if !range.fallback {
1464 match RangeCompound::try_serialize_number(value) {
1465 Some(s) => {
1466 let expected_key = match range.kind {
1469 RangeKind::RangeTo | RangeKind::RangeToInclusive => {
1470 if range.first.is_none() {
1471 "end"
1472 } else {
1473 ""
1474 }
1475 }
1476 _ => {
1477 if range.first.is_none() {
1478 "start"
1479 } else {
1480 "end"
1481 }
1482 }
1483 };
1484
1485 let max_fields = match range.kind {
1486 RangeKind::RangeFrom
1487 | RangeKind::RangeTo
1488 | RangeKind::RangeToInclusive => 1,
1489 RangeKind::Range | RangeKind::RangeInclusive => 2,
1490 };
1491
1492 if key != expected_key
1493 || (range.first.is_some() && max_fields < 2)
1494 || range.second.is_some()
1495 {
1496 range.fallback = true;
1497 } else if range.first.is_none() {
1498 range.first = Some((key, s));
1501 } else {
1502 range.second = Some((key, s));
1503 }
1504
1505 if !range.fallback {
1506 return Ok(());
1507 }
1508 }
1509 None => {
1510 range.fallback = true;
1511 }
1512 }
1513
1514 self.ser.output.write_char('(')?;
1515 if !self.ser.compact_structs() {
1516 self.ser.is_empty = Some(false);
1517 self.ser.start_indent()?;
1518 }
1519
1520 let buffered: [Option<(&'static str, crate::value::Number)>; 2] =
1522 [range.first.take(), range.second.take()];
1523
1524 for (bkey, bval) in buffered.into_iter().flatten() {
1525 ser::SerializeStruct::serialize_field(self, bkey, &bval)?;
1526 }
1527 }
1529 }
1530
1531 let mut restore_field = self.ser.pretty.as_mut().and_then(|(config, _)| {
1532 config.path_meta.take().map(|mut field| {
1533 if let Some(fields) = field.fields_mut() {
1534 config.path_meta = fields.remove(key);
1535 }
1536 field
1537 })
1538 });
1539
1540 if let State::First = self.state {
1541 self.state = State::Rest;
1542 } else {
1543 self.ser.output.write_char(',')?;
1544
1545 if let Some((ref config, ref pretty)) = self.ser.pretty {
1546 if pretty.indent <= config.depth_limit && !config.compact_structs {
1547 self.ser.output.write_str(&config.new_line)?;
1548 } else {
1549 self.ser.output.write_str(&config.separator)?;
1550 }
1551 }
1552 }
1553
1554 if !self.ser.compact_structs() {
1555 if let Some((ref config, ref pretty)) = self.ser.pretty {
1556 indent(&mut self.ser.output, config, pretty)?;
1557
1558 if let Some(ref field) = config.path_meta {
1559 for doc_line in field.doc().lines() {
1560 self.ser.output.write_str("/// ")?;
1561 self.ser.output.write_str(doc_line)?;
1562 self.ser.output.write_char('\n')?;
1563 indent(&mut self.ser.output, config, pretty)?;
1564 }
1565 }
1566 }
1567 }
1568
1569 self.ser.write_identifier(key)?;
1570 self.ser.output.write_char(':')?;
1571
1572 if let Some((ref config, _)) = self.ser.pretty {
1573 self.ser.output.write_str(&config.separator)?;
1574 }
1575
1576 guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1577
1578 if let Some((ref mut config, _)) = self.ser.pretty {
1579 core::mem::swap(&mut config.path_meta, &mut restore_field);
1580
1581 if let Some(ref mut field) = config.path_meta {
1582 if let Some(fields) = field.fields_mut() {
1583 if let Some(restore_field) = restore_field {
1584 fields.insert(key, restore_field);
1585 }
1586 }
1587 }
1588 };
1589
1590 Ok(())
1591 }
1592
1593 fn end(mut self) -> Result<()> {
1594 if let Some(ref mut range) = self.range {
1595 if !range.fallback {
1596 let sep = match range.kind {
1598 RangeKind::RangeInclusive | RangeKind::RangeToInclusive => "..=",
1599 _ => "..",
1600 };
1601
1602 match range.kind {
1603 RangeKind::RangeFrom => {
1604 if let Some((_, start)) = range.first.take() {
1605 start.serialize(&mut *self.ser)?;
1606 }
1607 self.ser.output.write_str("..")?;
1608 }
1609 RangeKind::RangeTo | RangeKind::RangeToInclusive => {
1610 self.ser.output.write_str(sep)?;
1611 if let Some((_, end)) = range.first.take() {
1612 end.serialize(&mut *self.ser)?;
1613 }
1614 }
1615 RangeKind::Range | RangeKind::RangeInclusive => {
1616 if let Some((_, start)) = range.first.take() {
1617 start.serialize(&mut *self.ser)?;
1618 }
1619 self.ser.output.write_str(sep)?;
1620 if let Some((_, end)) = range.second.take() {
1621 end.serialize(&mut *self.ser)?;
1622 }
1623 }
1624 }
1625 return Ok(());
1626 }
1627 }
1629
1630 if let State::Rest = self.state {
1631 if let Some((ref config, ref pretty)) = self.ser.pretty {
1632 if pretty.indent <= config.depth_limit && !config.compact_structs {
1633 self.ser.output.write_char(',')?;
1634 self.ser.output.write_str(&config.new_line)?;
1635 }
1636 }
1637 }
1638
1639 if !self.ser.compact_structs() {
1640 self.ser.end_indent()?;
1641 }
1642
1643 if !self.newtype_variant {
1644 self.ser.output.write_char(')')?;
1645 }
1646
1647 Ok(())
1648 }
1649}
1650
1651impl<'a, W: fmt::Write> ser::SerializeStructVariant for Compound<'a, W> {
1652 type Error = Error;
1653 type Ok = ();
1654
1655 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1656 where
1657 T: ?Sized + Serialize,
1658 {
1659 ser::SerializeStruct::serialize_field(self, key, value)
1660 }
1661
1662 fn end(self) -> Result<()> {
1663 ser::SerializeStruct::end(self)
1664 }
1665}