ron/ser/
mod.rs

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
22/// Serializes `value` into `writer`.
23///
24/// This function does not generate any newlines or nice formatting;
25/// if you want that, you can use [`to_writer_pretty`] instead.
26///
27/// `writer` is required to implement [`core::fmt::Write`]. To use [`std::io::Write`] instead,
28/// see [`Options::to_io_writer`](crate::options::Options::to_io_writer).
29pub 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
37/// Serializes `value` into `writer` in a pretty way.
38///
39/// `writer` is required to implement [`core::fmt::Write`]. To use [`std::io::Write`] instead,
40/// see [`Options::to_io_writer_pretty`](crate::options::Options::to_io_writer_pretty).
41pub 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
49/// Serializes `value` and returns it as string.
50///
51/// This function does not generate any newlines or nice formatting;
52/// if you want that, you can use [`to_string_pretty`] instead.
53pub fn to_string<T>(value: &T) -> Result<String>
54where
55    T: ?Sized + Serialize,
56{
57    Options::default().to_string(value)
58}
59
60/// Serializes `value` in the recommended RON layout in a pretty way.
61pub 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
68/// Pretty serializer state
69struct Pretty {
70    indent: usize,
71}
72
73/// Pretty serializer configuration.
74///
75/// # Examples
76///
77/// ```
78/// use ron::ser::PrettyConfig;
79///
80/// let my_config = PrettyConfig::new()
81///     .depth_limit(4)
82///     // definitely superior (okay, just joking)
83///     .indentor("\t");
84/// ```
85#[allow(clippy::struct_excessive_bools)]
86#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
87#[serde(default)]
88#[non_exhaustive]
89pub struct PrettyConfig {
90    /// Limit the pretty-ness up to the given depth.
91    pub depth_limit: usize,
92    /// New line string
93    pub new_line: Cow<'static, str>,
94    /// Indentation string
95    pub indentor: Cow<'static, str>,
96    /// Separator string
97    pub separator: Cow<'static, str>,
98    // Whether to emit struct names
99    pub struct_names: bool,
100    /// Separate tuple members with indentation
101    pub separate_tuple_members: bool,
102    /// Enumerate array items in comments
103    pub enumerate_arrays: bool,
104    /// Enable extensions. Only configures `implicit_some`,
105    ///  `unwrap_newtypes`, and `unwrap_variant_newtypes` for now.
106    pub extensions: Extensions,
107    /// Enable compact arrays, which do not insert new lines and indentation
108    ///  between the elements of an array
109    pub compact_arrays: bool,
110    /// Whether to serialize strings as escaped strings,
111    ///  or fall back onto raw strings if necessary.
112    pub escape_strings: bool,
113    /// Enable compact structs, which do not insert new lines and indentation
114    ///  between the fields of a struct
115    pub compact_structs: bool,
116    /// Enable compact maps, which do not insert new lines and indentation
117    ///  between the entries of a struct
118    pub compact_maps: bool,
119    /// Enable explicit number type suffixes like `1u16`
120    pub number_suffixes: bool,
121    /// Additional path-based field metadata to serialize
122    pub path_meta: Option<path_meta::Field>,
123}
124
125impl PrettyConfig {
126    /// Creates a default [`PrettyConfig`].
127    #[must_use]
128    pub fn new() -> Self {
129        Self::default()
130    }
131
132    /// Limits the pretty-formatting based on the number of indentations.
133    /// I.e., with a depth limit of 5, starting with an element of depth
134    /// (indentation level) 6, everything will be put into the same line,
135    /// without pretty formatting.
136    ///
137    /// Default: [`usize::MAX`]
138    #[must_use]
139    pub fn depth_limit(mut self, depth_limit: usize) -> Self {
140        self.depth_limit = depth_limit;
141
142        self
143    }
144
145    /// Configures the newlines used for serialization.
146    ///
147    /// Default: `\r\n` on Windows, `\n` otherwise
148    #[must_use]
149    pub fn new_line(mut self, new_line: impl Into<Cow<'static, str>>) -> Self {
150        self.new_line = new_line.into();
151
152        self
153    }
154
155    /// Configures the string sequence used for indentation.
156    ///
157    /// Default: 4 spaces
158    #[must_use]
159    pub fn indentor(mut self, indentor: impl Into<Cow<'static, str>>) -> Self {
160        self.indentor = indentor.into();
161
162        self
163    }
164
165    /// Configures the string sequence used to separate items inline.
166    ///
167    /// Default: 1 space
168    #[must_use]
169    pub fn separator(mut self, separator: impl Into<Cow<'static, str>>) -> Self {
170        self.separator = separator.into();
171
172        self
173    }
174
175    /// Configures whether to emit struct names.
176    ///
177    /// See also [`Extensions::EXPLICIT_STRUCT_NAMES`] for the extension equivalent.
178    ///
179    /// Default: `false`
180    #[must_use]
181    pub fn struct_names(mut self, struct_names: bool) -> Self {
182        self.struct_names = struct_names;
183
184        self
185    }
186
187    /// Configures whether tuples are single- or multi-line.
188    /// If set to `true`, tuples will have their fields indented and in new
189    /// lines. If set to `false`, tuples will be serialized without any
190    /// newlines or indentations.
191    ///
192    /// Default: `false`
193    #[must_use]
194    pub fn separate_tuple_members(mut self, separate_tuple_members: bool) -> Self {
195        self.separate_tuple_members = separate_tuple_members;
196
197        self
198    }
199
200    /// Configures whether a comment shall be added to every array element,
201    /// indicating the index.
202    ///
203    /// Default: `false`
204    #[must_use]
205    pub fn enumerate_arrays(mut self, enumerate_arrays: bool) -> Self {
206        self.enumerate_arrays = enumerate_arrays;
207
208        self
209    }
210
211    /// Configures whether every array should be a single line (`true`)
212    /// or a multi line one (`false`).
213    ///
214    /// When `false`, `["a","b"]` will serialize to
215    /// ```
216    /// [
217    ///   "a",
218    ///   "b",
219    /// ]
220    /// # ;
221    /// ```
222    /// When `true`, `["a","b"]` will instead serialize to
223    /// ```
224    /// ["a","b"]
225    /// # ;
226    /// ```
227    ///
228    /// Default: `false`
229    #[must_use]
230    pub fn compact_arrays(mut self, compact_arrays: bool) -> Self {
231        self.compact_arrays = compact_arrays;
232
233        self
234    }
235
236    /// Configures extensions
237    ///
238    /// Default: [`Extensions::empty()`]
239    #[must_use]
240    pub fn extensions(mut self, extensions: Extensions) -> Self {
241        self.extensions = extensions;
242
243        self
244    }
245
246    /// Configures whether strings should be serialized using escapes (true)
247    /// or fall back to raw strings if the string contains a `"` (false).
248    ///
249    /// When `true`, `"a\nb"` will serialize to
250    /// ```
251    /// "a\nb"
252    /// # ;
253    /// ```
254    /// When `false`, `"a\nb"` will instead serialize to
255    /// ```
256    /// "a
257    /// b"
258    /// # ;
259    /// ```
260    ///
261    /// Default: `true`
262    #[must_use]
263    pub fn escape_strings(mut self, escape_strings: bool) -> Self {
264        self.escape_strings = escape_strings;
265
266        self
267    }
268
269    /// Configures whether every struct should be a single line (`true`)
270    /// or a multi line one (`false`).
271    ///
272    /// When `false`, `Struct { a: 4, b: 2 }` will serialize to
273    /// ```ignore
274    /// Struct(
275    ///     a: 4,
276    ///     b: 2,
277    /// )
278    /// # ;
279    /// ```
280    /// When `true`, `Struct { a: 4, b: 2 }` will instead serialize to
281    /// ```ignore
282    /// Struct(a: 4, b: 2)
283    /// # ;
284    /// ```
285    ///
286    /// Default: `false`
287    #[must_use]
288    pub fn compact_structs(mut self, compact_structs: bool) -> Self {
289        self.compact_structs = compact_structs;
290
291        self
292    }
293
294    /// Configures whether every map should be a single line (`true`)
295    /// or a multi line one (`false`).
296    ///
297    /// When `false`, a map with entries `{ "a": 4, "b": 2 }` will serialize to
298    /// ```ignore
299    /// {
300    ///     "a": 4,
301    ///     "b": 2,
302    /// }
303    /// # ;
304    /// ```
305    /// When `true`, a map with entries `{ "a": 4, "b": 2 }` will instead
306    /// serialize to
307    /// ```ignore
308    /// {"a": 4, "b": 2}
309    /// # ;
310    /// ```
311    ///
312    /// Default: `false`
313    #[must_use]
314    pub fn compact_maps(mut self, compact_maps: bool) -> Self {
315        self.compact_maps = compact_maps;
316
317        self
318    }
319
320    /// Configures whether numbers should be printed without (`false`) or
321    /// with (`true`) their explicit type suffixes.
322    ///
323    /// When `false`, the integer `12345u16` will serialize to
324    /// ```ignore
325    /// 12345
326    /// # ;
327    /// ```
328    /// and the float `12345.6789f64` will serialize to
329    /// ```ignore
330    /// 12345.6789
331    /// # ;
332    /// ```
333    /// When `true`, the integer `12345u16` will serialize to
334    /// ```ignore
335    /// 12345u16
336    /// # ;
337    /// ```
338    /// and the float `12345.6789f64` will serialize to
339    /// ```ignore
340    /// 12345.6789f64
341    /// # ;
342    /// ```
343    ///
344    /// Default: `false`
345    #[must_use]
346    pub fn number_suffixes(mut self, number_suffixes: bool) -> Self {
347        self.number_suffixes = number_suffixes;
348
349        self
350    }
351}
352
353impl Default for PrettyConfig {
354    fn default() -> Self {
355        PrettyConfig {
356            depth_limit: usize::MAX,
357            new_line: if cfg!(not(target_os = "windows")) {
358                Cow::Borrowed("\n")
359            } else {
360                Cow::Borrowed("\r\n") // GRCOV_EXCL_LINE
361            },
362            indentor: Cow::Borrowed("    "),
363            separator: Cow::Borrowed(" "),
364            struct_names: false,
365            separate_tuple_members: false,
366            enumerate_arrays: false,
367            extensions: Extensions::empty(),
368            compact_arrays: false,
369            escape_strings: true,
370            compact_structs: false,
371            compact_maps: false,
372            number_suffixes: false,
373            path_meta: None,
374        }
375    }
376}
377
378/// The RON serializer.
379///
380/// You can just use [`to_string`] for deserializing a value.
381/// If you want it pretty-printed, take a look at [`to_string_pretty`].
382pub struct Serializer<W: fmt::Write> {
383    output: W,
384    pretty: Option<(PrettyConfig, Pretty)>,
385    default_extensions: Extensions,
386    is_empty: Option<bool>,
387    newtype_variant: bool,
388    recursion_limit: Option<usize>,
389    // Tracks the number of opened implicit `Some`s, set to 0 on backtracking
390    implicit_some_depth: usize,
391}
392
393fn indent<W: fmt::Write>(output: &mut W, config: &PrettyConfig, pretty: &Pretty) -> fmt::Result {
394    if pretty.indent <= config.depth_limit {
395        for _ in 0..pretty.indent {
396            output.write_str(&config.indentor)?;
397        }
398    }
399    Ok(())
400}
401
402impl<W: fmt::Write> Serializer<W> {
403    /// Creates a new [`Serializer`].
404    ///
405    /// Most of the time you can just use [`to_string`] or
406    /// [`to_string_pretty`].
407    pub fn new(writer: W, config: Option<PrettyConfig>) -> Result<Self> {
408        Self::with_options(writer, config, &Options::default())
409    }
410
411    /// Creates a new [`Serializer`].
412    ///
413    /// Most of the time you can just use [`to_string`] or
414    /// [`to_string_pretty`].
415    pub fn with_options(
416        mut writer: W,
417        config: Option<PrettyConfig>,
418        options: &Options,
419    ) -> Result<Self> {
420        if let Some(conf) = &config {
421            if !conf.new_line.chars().all(is_whitespace_char) {
422                return Err(Error::Message(String::from(
423                    "Invalid non-whitespace `PrettyConfig::new_line`",
424                )));
425            }
426            if !conf.indentor.chars().all(is_whitespace_char) {
427                return Err(Error::Message(String::from(
428                    "Invalid non-whitespace `PrettyConfig::indentor`",
429                )));
430            }
431            if !conf.separator.chars().all(is_whitespace_char) {
432                return Err(Error::Message(String::from(
433                    "Invalid non-whitespace `PrettyConfig::separator`",
434                )));
435            }
436
437            let non_default_extensions = !options.default_extensions;
438
439            for (extension_name, _) in (non_default_extensions & conf.extensions).iter_names() {
440                write!(writer, "#![enable({})]", extension_name.to_lowercase())?;
441                writer.write_str(&conf.new_line)?;
442            }
443        };
444        Ok(Serializer {
445            output: writer,
446            pretty: config.map(|conf| (conf, Pretty { indent: 0 })),
447            default_extensions: options.default_extensions,
448            is_empty: None,
449            newtype_variant: false,
450            recursion_limit: options.recursion_limit,
451            implicit_some_depth: 0,
452        })
453    }
454
455    /// Unwrap the `Writer` from the `Serializer`.
456    #[inline]
457    pub fn into_inner(self) -> W {
458        self.output
459    }
460
461    fn separate_tuple_members(&self) -> bool {
462        self.pretty
463            .as_ref()
464            .map_or(false, |(ref config, _)| config.separate_tuple_members)
465    }
466
467    fn compact_arrays(&self) -> bool {
468        self.pretty
469            .as_ref()
470            .map_or(false, |(ref config, _)| config.compact_arrays)
471    }
472
473    fn compact_structs(&self) -> bool {
474        self.pretty
475            .as_ref()
476            .map_or(false, |(ref config, _)| config.compact_structs)
477    }
478
479    fn compact_maps(&self) -> bool {
480        self.pretty
481            .as_ref()
482            .map_or(false, |(ref config, _)| config.compact_maps)
483    }
484
485    fn number_suffixes(&self) -> bool {
486        self.pretty
487            .as_ref()
488            .map_or(false, |(ref config, _)| config.number_suffixes)
489    }
490
491    fn extensions(&self) -> Extensions {
492        self.default_extensions
493            | self
494                .pretty
495                .as_ref()
496                .map_or(Extensions::empty(), |(ref config, _)| config.extensions)
497    }
498
499    fn escape_strings(&self) -> bool {
500        self.pretty
501            .as_ref()
502            .map_or(true, |(ref config, _)| config.escape_strings)
503    }
504
505    fn start_indent(&mut self) -> Result<()> {
506        if let Some((ref config, ref mut pretty)) = self.pretty {
507            pretty.indent += 1;
508            if pretty.indent <= config.depth_limit {
509                let is_empty = self.is_empty.unwrap_or(false);
510
511                if !is_empty {
512                    self.output.write_str(&config.new_line)?;
513                }
514            }
515        }
516        Ok(())
517    }
518
519    fn indent(&mut self) -> fmt::Result {
520        if let Some((ref config, ref pretty)) = self.pretty {
521            indent(&mut self.output, config, pretty)?;
522        }
523        Ok(())
524    }
525
526    fn end_indent(&mut self) -> fmt::Result {
527        if let Some((ref config, ref mut pretty)) = self.pretty {
528            if pretty.indent <= config.depth_limit {
529                let is_empty = self.is_empty.unwrap_or(false);
530
531                if !is_empty {
532                    for _ in 1..pretty.indent {
533                        self.output.write_str(&config.indentor)?;
534                    }
535                }
536            }
537            pretty.indent -= 1;
538
539            self.is_empty = None;
540        }
541        Ok(())
542    }
543
544    fn serialize_escaped_str(&mut self, value: &str) -> fmt::Result {
545        self.output.write_char('"')?;
546        let mut scalar = [0u8; 4];
547        for c in value.chars().flat_map(char::escape_debug) {
548            self.output.write_str(c.encode_utf8(&mut scalar))?;
549        }
550        self.output.write_char('"')?;
551        Ok(())
552    }
553
554    fn serialize_unescaped_or_raw_str(&mut self, value: &str) -> fmt::Result {
555        if value.contains('"') || value.contains('\\') {
556            let (_, num_consecutive_hashes) =
557                value.chars().fold((0, 0), |(count, max), c| match c {
558                    '#' => (count + 1, max.max(count + 1)),
559                    _ => (0_usize, max),
560                });
561            let hashes: String = "#".repeat(num_consecutive_hashes + 1);
562            self.output.write_char('r')?;
563            self.output.write_str(&hashes)?;
564            self.output.write_char('"')?;
565            self.output.write_str(value)?;
566            self.output.write_char('"')?;
567            self.output.write_str(&hashes)?;
568        } else {
569            self.output.write_char('"')?;
570            self.output.write_str(value)?;
571            self.output.write_char('"')?;
572        }
573        Ok(())
574    }
575
576    fn serialize_escaped_byte_str(&mut self, value: &[u8]) -> fmt::Result {
577        self.output.write_str("b\"")?;
578        for c in value.iter().flat_map(|c| core::ascii::escape_default(*c)) {
579            self.output.write_char(char::from(c))?;
580        }
581        self.output.write_char('"')?;
582        Ok(())
583    }
584
585    fn serialize_unescaped_or_raw_byte_str(&mut self, value: &str) -> fmt::Result {
586        if value.contains('"') || value.contains('\\') {
587            let (_, num_consecutive_hashes) =
588                value.chars().fold((0, 0), |(count, max), c| match c {
589                    '#' => (count + 1, max.max(count + 1)),
590                    _ => (0_usize, max),
591                });
592            let hashes: String = "#".repeat(num_consecutive_hashes + 1);
593            self.output.write_str("br")?;
594            self.output.write_str(&hashes)?;
595            self.output.write_char('"')?;
596            self.output.write_str(value)?;
597            self.output.write_char('"')?;
598            self.output.write_str(&hashes)?;
599        } else {
600            self.output.write_str("b\"")?;
601            self.output.write_str(value)?;
602            self.output.write_char('"')?;
603        }
604        Ok(())
605    }
606
607    fn serialize_sint(&mut self, value: impl Into<LargeSInt>, suffix: &str) -> Result<()> {
608        // TODO optimize
609        write!(self.output, "{}", value.into())?;
610
611        if self.number_suffixes() {
612            write!(self.output, "{}", suffix)?;
613        }
614
615        Ok(())
616    }
617
618    fn serialize_uint(&mut self, value: impl Into<LargeUInt>, suffix: &str) -> Result<()> {
619        // TODO optimize
620        write!(self.output, "{}", value.into())?;
621
622        if self.number_suffixes() {
623            write!(self.output, "{}", suffix)?;
624        }
625
626        Ok(())
627    }
628
629    fn write_identifier(&mut self, name: &str) -> Result<()> {
630        self.validate_identifier(name)?;
631        let mut chars = name.chars();
632        if !chars.next().map_or(false, is_ident_first_char)
633            || !chars.all(is_xid_continue)
634            || [
635                "true", "false", "Some", "None", "inf", "inff32", "inff64", "NaN", "NaNf32",
636                "NaNf64",
637            ]
638            .contains(&name)
639        {
640            self.output.write_str("r#")?;
641        }
642        self.output.write_str(name)?;
643        Ok(())
644    }
645
646    #[allow(clippy::unused_self)]
647    fn validate_identifier(&self, name: &str) -> Result<()> {
648        if name.is_empty() || !name.chars().all(is_ident_raw_char) {
649            return Err(Error::InvalidIdentifier(name.into()));
650        }
651        Ok(())
652    }
653
654    /// Checks if struct names should be emitted
655    ///
656    /// Note that when using the `explicit_struct_names` extension, this method will use an OR operation on the extension and the [`PrettyConfig::struct_names`] option. See also [`Extensions::EXPLICIT_STRUCT_NAMES`] for the extension equivalent.
657    fn struct_names(&self) -> bool {
658        self.extensions()
659            .contains(Extensions::EXPLICIT_STRUCT_NAMES)
660            || self
661                .pretty
662                .as_ref()
663                .map_or(false, |(pc, _)| pc.struct_names)
664    }
665}
666
667macro_rules! guard_recursion {
668    ($self:expr => $expr:expr) => {{
669        if let Some(limit) = &mut $self.recursion_limit {
670            if let Some(new_limit) = limit.checked_sub(1) {
671                *limit = new_limit;
672            } else {
673                return Err(Error::ExceededRecursionLimit);
674            }
675        }
676
677        let result = $expr;
678
679        if let Some(limit) = &mut $self.recursion_limit {
680            *limit = limit.saturating_add(1);
681        }
682
683        result
684    }};
685}
686
687impl<'a, W: fmt::Write> ser::Serializer for &'a mut Serializer<W> {
688    type Error = Error;
689    type Ok = ();
690    type SerializeMap = Compound<'a, W>;
691    type SerializeSeq = Compound<'a, W>;
692    type SerializeStruct = Compound<'a, W>;
693    type SerializeStructVariant = Compound<'a, W>;
694    type SerializeTuple = Compound<'a, W>;
695    type SerializeTupleStruct = Compound<'a, W>;
696    type SerializeTupleVariant = Compound<'a, W>;
697
698    fn serialize_bool(self, v: bool) -> Result<()> {
699        self.output.write_str(if v { "true" } else { "false" })?;
700        Ok(())
701    }
702
703    fn serialize_i8(self, v: i8) -> Result<()> {
704        self.serialize_sint(v, "i8")
705    }
706
707    fn serialize_i16(self, v: i16) -> Result<()> {
708        self.serialize_sint(v, "i16")
709    }
710
711    fn serialize_i32(self, v: i32) -> Result<()> {
712        self.serialize_sint(v, "i32")
713    }
714
715    fn serialize_i64(self, v: i64) -> Result<()> {
716        self.serialize_sint(v, "i64")
717    }
718
719    #[cfg(feature = "integer128")]
720    fn serialize_i128(self, v: i128) -> Result<()> {
721        self.serialize_sint(v, "i128")
722    }
723
724    fn serialize_u8(self, v: u8) -> Result<()> {
725        self.serialize_uint(v, "u8")
726    }
727
728    fn serialize_u16(self, v: u16) -> Result<()> {
729        self.serialize_uint(v, "u16")
730    }
731
732    fn serialize_u32(self, v: u32) -> Result<()> {
733        self.serialize_uint(v, "u32")
734    }
735
736    fn serialize_u64(self, v: u64) -> Result<()> {
737        self.serialize_uint(v, "u64")
738    }
739
740    #[cfg(feature = "integer128")]
741    fn serialize_u128(self, v: u128) -> Result<()> {
742        self.serialize_uint(v, "u128")
743    }
744
745    fn serialize_f32(self, v: f32) -> Result<()> {
746        if v.is_nan() && v.is_sign_negative() {
747            write!(self.output, "-")?;
748        }
749
750        write!(self.output, "{}", v)?;
751
752        // Equivalent to v.fract() == 0.0
753        // See: https://docs.rs/num-traits/0.2.19/src/num_traits/float.rs.html#459-465
754        if v % 1. == 0.0 {
755            write!(self.output, ".0")?;
756        }
757
758        if self.number_suffixes() {
759            write!(self.output, "f32")?;
760        }
761
762        Ok(())
763    }
764
765    fn serialize_f64(self, v: f64) -> Result<()> {
766        if v.is_nan() && v.is_sign_negative() {
767            write!(self.output, "-")?;
768        }
769
770        write!(self.output, "{}", v)?;
771
772        // Equivalent to v.fract() == 0.0
773        // See: https://docs.rs/num-traits/0.2.19/src/num_traits/float.rs.html#459-465
774        if v % 1. == 0.0 {
775            write!(self.output, ".0")?;
776        }
777
778        if self.number_suffixes() {
779            write!(self.output, "f64")?;
780        }
781
782        Ok(())
783    }
784
785    fn serialize_char(self, v: char) -> Result<()> {
786        self.output.write_char('\'')?;
787        if v == '\\' || v == '\'' {
788            self.output.write_char('\\')?;
789        }
790        write!(self.output, "{}", v)?;
791        self.output.write_char('\'')?;
792        Ok(())
793    }
794
795    fn serialize_str(self, v: &str) -> Result<()> {
796        if self.escape_strings() {
797            self.serialize_escaped_str(v)?;
798        } else {
799            self.serialize_unescaped_or_raw_str(v)?;
800        }
801
802        Ok(())
803    }
804
805    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
806        // We need to fall back to escaping if the byte string would be invalid UTF-8
807        if !self.escape_strings() {
808            if let Ok(v) = core::str::from_utf8(v) {
809                return self
810                    .serialize_unescaped_or_raw_byte_str(v)
811                    .map_err(Error::from);
812            }
813        }
814
815        self.serialize_escaped_byte_str(v)?;
816
817        Ok(())
818    }
819
820    fn serialize_none(self) -> Result<()> {
821        // We no longer need to keep track of the depth
822        let implicit_some_depth = self.implicit_some_depth;
823        self.implicit_some_depth = 0;
824
825        for _ in 0..implicit_some_depth {
826            self.output.write_str("Some(")?;
827        }
828        self.output.write_str("None")?;
829        for _ in 0..implicit_some_depth {
830            self.output.write_char(')')?;
831        }
832
833        Ok(())
834    }
835
836    fn serialize_some<T>(self, value: &T) -> Result<()>
837    where
838        T: ?Sized + Serialize,
839    {
840        let implicit_some = self.extensions().contains(Extensions::IMPLICIT_SOME);
841        if implicit_some {
842            self.implicit_some_depth += 1;
843        } else {
844            self.newtype_variant = self
845                .extensions()
846                .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
847            self.output.write_str("Some(")?;
848        }
849        guard_recursion! { self => value.serialize(&mut *self)? };
850        if implicit_some {
851            self.implicit_some_depth = 0;
852        } else {
853            self.output.write_char(')')?;
854            self.newtype_variant = false;
855        }
856
857        Ok(())
858    }
859
860    fn serialize_unit(self) -> Result<()> {
861        if !self.newtype_variant {
862            self.output.write_str("()")?;
863        }
864
865        Ok(())
866    }
867
868    fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
869        if self.struct_names() && !self.newtype_variant {
870            self.write_identifier(name)?;
871
872            Ok(())
873        } else {
874            self.validate_identifier(name)?;
875            self.serialize_unit()
876        }
877    }
878
879    fn serialize_unit_variant(
880        self,
881        name: &'static str,
882        _variant_index: u32,
883        variant: &'static str,
884    ) -> Result<()> {
885        self.validate_identifier(name)?;
886        self.write_identifier(variant)?;
887
888        Ok(())
889    }
890
891    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
892    where
893        T: ?Sized + Serialize,
894    {
895        if name == crate::value::raw::RAW_VALUE_TOKEN {
896            let implicit_some_depth = self.implicit_some_depth;
897            self.implicit_some_depth = 0;
898
899            for _ in 0..implicit_some_depth {
900                self.output.write_str("Some(")?;
901            }
902
903            guard_recursion! { self => value.serialize(raw::Serializer::new(self)) }?;
904
905            for _ in 0..implicit_some_depth {
906                self.output.write_char(')')?;
907            }
908
909            return Ok(());
910        }
911
912        if self.extensions().contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
913            self.newtype_variant = false;
914
915            self.validate_identifier(name)?;
916
917            return guard_recursion! { self => value.serialize(&mut *self) };
918        }
919
920        if self.struct_names() {
921            self.write_identifier(name)?;
922        } else {
923            self.validate_identifier(name)?;
924        }
925
926        self.implicit_some_depth = 0;
927
928        self.output.write_char('(')?;
929        guard_recursion! { self => value.serialize(&mut *self)? };
930        self.output.write_char(')')?;
931
932        Ok(())
933    }
934
935    fn serialize_newtype_variant<T>(
936        self,
937        name: &'static str,
938        _variant_index: u32,
939        variant: &'static str,
940        value: &T,
941    ) -> Result<()>
942    where
943        T: ?Sized + Serialize,
944    {
945        self.validate_identifier(name)?;
946        self.write_identifier(variant)?;
947        self.output.write_char('(')?;
948
949        self.newtype_variant = self
950            .extensions()
951            .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
952        self.implicit_some_depth = 0;
953
954        guard_recursion! { self => value.serialize(&mut *self)? };
955
956        self.newtype_variant = false;
957
958        self.output.write_char(')')?;
959        Ok(())
960    }
961
962    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
963        self.newtype_variant = false;
964        self.implicit_some_depth = 0;
965
966        self.output.write_char('[')?;
967
968        if !self.compact_arrays() {
969            if let Some(len) = len {
970                self.is_empty = Some(len == 0);
971            }
972
973            self.start_indent()?;
974        }
975
976        Ok(Compound::new(self, false))
977    }
978
979    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
980        let old_newtype_variant = self.newtype_variant;
981        self.newtype_variant = false;
982        self.implicit_some_depth = 0;
983
984        if !old_newtype_variant {
985            self.output.write_char('(')?;
986        }
987
988        if self.separate_tuple_members() {
989            self.is_empty = Some(len == 0);
990
991            self.start_indent()?;
992        }
993
994        Ok(Compound::new(self, old_newtype_variant))
995    }
996
997    fn serialize_tuple_struct(
998        self,
999        name: &'static str,
1000        len: usize,
1001    ) -> Result<Self::SerializeTupleStruct> {
1002        if self.struct_names() && !self.newtype_variant {
1003            self.write_identifier(name)?;
1004        } else {
1005            self.validate_identifier(name)?;
1006        }
1007
1008        self.serialize_tuple(len)
1009    }
1010
1011    fn serialize_tuple_variant(
1012        self,
1013        name: &'static str,
1014        _variant_index: u32,
1015        variant: &'static str,
1016        len: usize,
1017    ) -> Result<Self::SerializeTupleVariant> {
1018        self.newtype_variant = false;
1019        self.implicit_some_depth = 0;
1020
1021        self.validate_identifier(name)?;
1022        self.write_identifier(variant)?;
1023        self.output.write_char('(')?;
1024
1025        if self.separate_tuple_members() {
1026            self.is_empty = Some(len == 0);
1027
1028            self.start_indent()?;
1029        }
1030
1031        Ok(Compound::new(self, false))
1032    }
1033
1034    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
1035        self.newtype_variant = false;
1036        self.implicit_some_depth = 0;
1037
1038        self.output.write_char('{')?;
1039
1040        if !self.compact_maps() {
1041            if let Some(len) = len {
1042                self.is_empty = Some(len == 0);
1043            }
1044
1045            self.start_indent()?;
1046        }
1047
1048        Ok(Compound::new(self, false))
1049    }
1050
1051    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
1052        let old_newtype_variant = self.newtype_variant;
1053        self.newtype_variant = false;
1054        self.implicit_some_depth = 0;
1055
1056        if old_newtype_variant {
1057            self.validate_identifier(name)?;
1058        } else {
1059            if self.struct_names() {
1060                self.write_identifier(name)?;
1061            } else {
1062                self.validate_identifier(name)?;
1063            }
1064            self.output.write_char('(')?;
1065        }
1066
1067        if !self.compact_structs() {
1068            self.is_empty = Some(len == 0);
1069            self.start_indent()?;
1070        }
1071
1072        Ok(Compound::new(self, old_newtype_variant))
1073    }
1074
1075    fn serialize_struct_variant(
1076        self,
1077        name: &'static str,
1078        _variant_index: u32,
1079        variant: &'static str,
1080        len: usize,
1081    ) -> Result<Self::SerializeStructVariant> {
1082        self.newtype_variant = false;
1083        self.implicit_some_depth = 0;
1084
1085        self.validate_identifier(name)?;
1086        self.write_identifier(variant)?;
1087        self.output.write_char('(')?;
1088
1089        if !self.compact_structs() {
1090            self.is_empty = Some(len == 0);
1091            self.start_indent()?;
1092        }
1093
1094        Ok(Compound::new(self, false))
1095    }
1096}
1097
1098enum State {
1099    First,
1100    Rest,
1101}
1102
1103#[doc(hidden)]
1104pub struct Compound<'a, W: fmt::Write> {
1105    ser: &'a mut Serializer<W>,
1106    state: State,
1107    newtype_variant: bool,
1108    sequence_index: usize,
1109}
1110
1111impl<'a, W: fmt::Write> Compound<'a, W> {
1112    fn new(ser: &'a mut Serializer<W>, newtype_variant: bool) -> Self {
1113        Compound {
1114            ser,
1115            state: State::First,
1116            newtype_variant,
1117            sequence_index: 0,
1118        }
1119    }
1120}
1121
1122impl<'a, W: fmt::Write> Drop for Compound<'a, W> {
1123    fn drop(&mut self) {
1124        if let Some(limit) = &mut self.ser.recursion_limit {
1125            *limit = limit.saturating_add(1);
1126        }
1127    }
1128}
1129
1130impl<'a, W: fmt::Write> ser::SerializeSeq for Compound<'a, W> {
1131    type Error = Error;
1132    type Ok = ();
1133
1134    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1135    where
1136        T: ?Sized + Serialize,
1137    {
1138        if let State::First = self.state {
1139            self.state = State::Rest;
1140        } else {
1141            self.ser.output.write_char(',')?;
1142            if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1143                if pretty.indent <= config.depth_limit && !config.compact_arrays {
1144                    self.ser.output.write_str(&config.new_line)?;
1145                } else {
1146                    self.ser.output.write_str(&config.separator)?;
1147                }
1148            }
1149        }
1150
1151        if !self.ser.compact_arrays() {
1152            self.ser.indent()?;
1153        }
1154
1155        if let Some((ref mut config, ref mut pretty)) = self.ser.pretty {
1156            if pretty.indent <= config.depth_limit && config.enumerate_arrays {
1157                write!(self.ser.output, "/*[{}]*/ ", self.sequence_index)?;
1158                self.sequence_index += 1;
1159            }
1160        }
1161
1162        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1163
1164        Ok(())
1165    }
1166
1167    fn end(self) -> Result<()> {
1168        if let State::Rest = self.state {
1169            if let Some((ref config, ref mut pretty)) = self.ser.pretty {
1170                if pretty.indent <= config.depth_limit && !config.compact_arrays {
1171                    self.ser.output.write_char(',')?;
1172                    self.ser.output.write_str(&config.new_line)?;
1173                }
1174            }
1175        }
1176
1177        if !self.ser.compact_arrays() {
1178            self.ser.end_indent()?;
1179        }
1180
1181        // seq always disables `self.newtype_variant`
1182        self.ser.output.write_char(']')?;
1183        Ok(())
1184    }
1185}
1186
1187impl<'a, W: fmt::Write> ser::SerializeTuple for Compound<'a, W> {
1188    type Error = Error;
1189    type Ok = ();
1190
1191    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
1192    where
1193        T: ?Sized + Serialize,
1194    {
1195        if let State::First = self.state {
1196            self.state = State::Rest;
1197        } else {
1198            self.ser.output.write_char(',')?;
1199            if let Some((ref config, ref pretty)) = self.ser.pretty {
1200                if pretty.indent <= config.depth_limit && self.ser.separate_tuple_members() {
1201                    self.ser.output.write_str(&config.new_line)?;
1202                } else {
1203                    self.ser.output.write_str(&config.separator)?;
1204                }
1205            }
1206        }
1207
1208        if self.ser.separate_tuple_members() {
1209            self.ser.indent()?;
1210        }
1211
1212        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1213
1214        Ok(())
1215    }
1216
1217    fn end(self) -> Result<()> {
1218        if let State::Rest = self.state {
1219            if let Some((ref config, ref pretty)) = self.ser.pretty {
1220                if self.ser.separate_tuple_members() && pretty.indent <= config.depth_limit {
1221                    self.ser.output.write_char(',')?;
1222                    self.ser.output.write_str(&config.new_line)?;
1223                }
1224            }
1225        }
1226        if self.ser.separate_tuple_members() {
1227            self.ser.end_indent()?;
1228        }
1229
1230        if !self.newtype_variant {
1231            self.ser.output.write_char(')')?;
1232        }
1233
1234        Ok(())
1235    }
1236}
1237
1238// Same thing but for tuple structs.
1239impl<'a, W: fmt::Write> ser::SerializeTupleStruct for Compound<'a, W> {
1240    type Error = Error;
1241    type Ok = ();
1242
1243    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1244    where
1245        T: ?Sized + Serialize,
1246    {
1247        ser::SerializeTuple::serialize_element(self, value)
1248    }
1249
1250    fn end(self) -> Result<()> {
1251        ser::SerializeTuple::end(self)
1252    }
1253}
1254
1255impl<'a, W: fmt::Write> ser::SerializeTupleVariant for Compound<'a, W> {
1256    type Error = Error;
1257    type Ok = ();
1258
1259    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
1260    where
1261        T: ?Sized + Serialize,
1262    {
1263        ser::SerializeTuple::serialize_element(self, value)
1264    }
1265
1266    fn end(self) -> Result<()> {
1267        ser::SerializeTuple::end(self)
1268    }
1269}
1270
1271impl<'a, W: fmt::Write> ser::SerializeMap for Compound<'a, W> {
1272    type Error = Error;
1273    type Ok = ();
1274
1275    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
1276    where
1277        T: ?Sized + Serialize,
1278    {
1279        if let State::First = self.state {
1280            self.state = State::Rest;
1281        } else {
1282            self.ser.output.write_char(',')?;
1283
1284            if let Some((ref config, ref pretty)) = self.ser.pretty {
1285                if pretty.indent <= config.depth_limit && !config.compact_maps {
1286                    self.ser.output.write_str(&config.new_line)?;
1287                } else {
1288                    self.ser.output.write_str(&config.separator)?;
1289                }
1290            }
1291        }
1292
1293        if !self.ser.compact_maps() {
1294            self.ser.indent()?;
1295        }
1296
1297        guard_recursion! { self.ser => key.serialize(&mut *self.ser) }
1298    }
1299
1300    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
1301    where
1302        T: ?Sized + Serialize,
1303    {
1304        self.ser.output.write_char(':')?;
1305
1306        if let Some((ref config, _)) = self.ser.pretty {
1307            self.ser.output.write_str(&config.separator)?;
1308        }
1309
1310        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1311
1312        Ok(())
1313    }
1314
1315    fn end(self) -> Result<()> {
1316        if let State::Rest = self.state {
1317            if let Some((ref config, ref pretty)) = self.ser.pretty {
1318                if pretty.indent <= config.depth_limit && !config.compact_maps {
1319                    self.ser.output.write_char(',')?;
1320                    self.ser.output.write_str(&config.new_line)?;
1321                }
1322            }
1323        }
1324
1325        if !self.ser.compact_maps() {
1326            self.ser.end_indent()?;
1327        }
1328
1329        // map always disables `self.newtype_variant`
1330        self.ser.output.write_char('}')?;
1331        Ok(())
1332    }
1333}
1334
1335impl<'a, W: fmt::Write> ser::SerializeStruct for Compound<'a, W> {
1336    type Error = Error;
1337    type Ok = ();
1338
1339    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1340    where
1341        T: ?Sized + Serialize,
1342    {
1343        let mut restore_field = self.ser.pretty.as_mut().and_then(|(config, _)| {
1344            config.path_meta.take().map(|mut field| {
1345                if let Some(fields) = field.fields_mut() {
1346                    config.path_meta = fields.remove(key);
1347                }
1348                field
1349            })
1350        });
1351
1352        if let State::First = self.state {
1353            self.state = State::Rest;
1354        } else {
1355            self.ser.output.write_char(',')?;
1356
1357            if let Some((ref config, ref pretty)) = self.ser.pretty {
1358                if pretty.indent <= config.depth_limit && !config.compact_structs {
1359                    self.ser.output.write_str(&config.new_line)?;
1360                } else {
1361                    self.ser.output.write_str(&config.separator)?;
1362                }
1363            }
1364        }
1365
1366        if !self.ser.compact_structs() {
1367            if let Some((ref config, ref pretty)) = self.ser.pretty {
1368                indent(&mut self.ser.output, config, pretty)?;
1369
1370                if let Some(ref field) = config.path_meta {
1371                    for doc_line in field.doc().lines() {
1372                        self.ser.output.write_str("/// ")?;
1373                        self.ser.output.write_str(doc_line)?;
1374                        self.ser.output.write_char('\n')?;
1375                        indent(&mut self.ser.output, config, pretty)?;
1376                    }
1377                }
1378            }
1379        }
1380
1381        self.ser.write_identifier(key)?;
1382        self.ser.output.write_char(':')?;
1383
1384        if let Some((ref config, _)) = self.ser.pretty {
1385            self.ser.output.write_str(&config.separator)?;
1386        }
1387
1388        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1389
1390        if let Some((ref mut config, _)) = self.ser.pretty {
1391            core::mem::swap(&mut config.path_meta, &mut restore_field);
1392
1393            if let Some(ref mut field) = config.path_meta {
1394                if let Some(fields) = field.fields_mut() {
1395                    if let Some(restore_field) = restore_field {
1396                        fields.insert(key, restore_field);
1397                    }
1398                }
1399            }
1400        };
1401
1402        Ok(())
1403    }
1404
1405    fn end(self) -> Result<()> {
1406        if let State::Rest = self.state {
1407            if let Some((ref config, ref pretty)) = self.ser.pretty {
1408                if pretty.indent <= config.depth_limit && !config.compact_structs {
1409                    self.ser.output.write_char(',')?;
1410                    self.ser.output.write_str(&config.new_line)?;
1411                }
1412            }
1413        }
1414
1415        if !self.ser.compact_structs() {
1416            self.ser.end_indent()?;
1417        }
1418
1419        if !self.newtype_variant {
1420            self.ser.output.write_char(')')?;
1421        }
1422
1423        Ok(())
1424    }
1425}
1426
1427impl<'a, W: fmt::Write> ser::SerializeStructVariant for Compound<'a, W> {
1428    type Error = Error;
1429    type Ok = ();
1430
1431    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
1432    where
1433        T: ?Sized + Serialize,
1434    {
1435        ser::SerializeStruct::serialize_field(self, key, value)
1436    }
1437
1438    fn end(self) -> Result<()> {
1439        ser::SerializeStruct::end(self)
1440    }
1441}