1
use alloc::{borrow::Cow, string::String};
2
use core::fmt;
3

            
4
use serde::{ser, ser::Serialize};
5
use serde_derive::{Deserialize, Serialize};
6
use unicode_ident::is_xid_continue;
7

            
8
use 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

            
15
pub mod path_meta;
16

            
17
mod raw;
18
#[cfg(test)]
19
mod tests;
20
mod 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).
29
360
pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
30
360
where
31
360
    W: fmt::Write,
32
360
    T: ?Sized + Serialize,
33
{
34
360
    Options::default().to_writer(writer, value)
35
360
}
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).
41
360
pub fn to_writer_pretty<W, T>(writer: W, value: &T, config: PrettyConfig) -> Result<()>
42
360
where
43
360
    W: fmt::Write,
44
360
    T: ?Sized + Serialize,
45
{
46
360
    Options::default().to_writer_pretty(writer, value, config)
47
360
}
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.
53
1744
pub fn to_string<T>(value: &T) -> Result<String>
54
1744
where
55
1744
    T: ?Sized + Serialize,
56
{
57
1744
    Options::default().to_string(value)
58
1744
}
59

            
60
/// Serializes `value` in the recommended RON layout in a pretty way.
61
1512
pub fn to_string_pretty<T>(value: &T, config: PrettyConfig) -> Result<String>
62
1512
where
63
1512
    T: ?Sized + Serialize,
64
{
65
1512
    Options::default().to_string_pretty(value, config)
66
1512
}
67

            
68
/// Pretty serializer state
69
struct 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]
89
pub 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
    /// Enable compact range syntax, e.g. `0..5` instead of `(start: 0, end: 5)`.
124
    pub compact_ranges: bool,
125
}
126

            
127
impl PrettyConfig {
128
    /// Creates a default [`PrettyConfig`].
129
    #[must_use]
130
6510
    pub fn new() -> Self {
131
6510
        Self::default()
132
6510
    }
133

            
134
    /// Limits the pretty-formatting based on the number of indentations.
135
    /// I.e., with a depth limit of 5, starting with an element of depth
136
    /// (indentation level) 6, everything will be put into the same line,
137
    /// without pretty formatting.
138
    ///
139
    /// Default: [`usize::MAX`]
140
    #[must_use]
141
930
    pub fn depth_limit(mut self, depth_limit: usize) -> Self {
142
930
        self.depth_limit = depth_limit;
143

            
144
930
        self
145
930
    }
146

            
147
    /// Configures the newlines used for serialization.
148
    ///
149
    /// Default: `\r\n` on Windows, `\n` otherwise
150
    #[must_use]
151
68
    pub fn new_line(mut self, new_line: impl Into<Cow<'static, str>>) -> Self {
152
68
        self.new_line = new_line.into();
153

            
154
68
        self
155
68
    }
156

            
157
    /// Configures the string sequence used for indentation.
158
    ///
159
    /// Default: 4 spaces
160
    #[must_use]
161
20
    pub fn indentor(mut self, indentor: impl Into<Cow<'static, str>>) -> Self {
162
20
        self.indentor = indentor.into();
163

            
164
20
        self
165
20
    }
166

            
167
    /// Configures the string sequence used to separate items inline.
168
    ///
169
    /// Default: 1 space
170
    #[must_use]
171
24
    pub fn separator(mut self, separator: impl Into<Cow<'static, str>>) -> Self {
172
24
        self.separator = separator.into();
173

            
174
24
        self
175
24
    }
176

            
177
    /// Configures whether to emit struct names.
178
    ///
179
    /// See also [`Extensions::EXPLICIT_STRUCT_NAMES`] for the extension equivalent.
180
    ///
181
    /// Default: `false`
182
    #[must_use]
183
5060
    pub fn struct_names(mut self, struct_names: bool) -> Self {
184
5060
        self.struct_names = struct_names;
185

            
186
5060
        self
187
5060
    }
188

            
189
    /// Configures whether tuples are single- or multi-line.
190
    /// If set to `true`, tuples will have their fields indented and in new
191
    /// lines. If set to `false`, tuples will be serialized without any
192
    /// newlines or indentations.
193
    ///
194
    /// Default: `false`
195
    #[must_use]
196
1550
    pub fn separate_tuple_members(mut self, separate_tuple_members: bool) -> Self {
197
1550
        self.separate_tuple_members = separate_tuple_members;
198

            
199
1550
        self
200
1550
    }
201

            
202
    /// Configures whether a comment shall be added to every array element,
203
    /// indicating the index.
204
    ///
205
    /// Default: `false`
206
    #[must_use]
207
2170
    pub fn enumerate_arrays(mut self, enumerate_arrays: bool) -> Self {
208
2170
        self.enumerate_arrays = enumerate_arrays;
209

            
210
2170
        self
211
2170
    }
212

            
213
    /// Configures whether every array should be a single line (`true`)
214
    /// or a multi line one (`false`).
215
    ///
216
    /// When `false`, `["a","b"]` will serialize to
217
    /// ```
218
    /// [
219
    ///   "a",
220
    ///   "b",
221
    /// ]
222
    /// # ;
223
    /// ```
224
    /// When `true`, `["a","b"]` will instead serialize to
225
    /// ```
226
    /// ["a","b"]
227
    /// # ;
228
    /// ```
229
    ///
230
    /// Default: `false`
231
    #[must_use]
232
1240
    pub fn compact_arrays(mut self, compact_arrays: bool) -> Self {
233
1240
        self.compact_arrays = compact_arrays;
234

            
235
1240
        self
236
1240
    }
237

            
238
    /// Configures extensions
239
    ///
240
    /// Default: [`Extensions::empty()`]
241
    #[must_use]
242
13950
    pub fn extensions(mut self, extensions: Extensions) -> Self {
243
13950
        self.extensions = extensions;
244

            
245
13950
        self
246
13950
    }
247

            
248
    /// Configures whether strings should be serialized using escapes (true)
249
    /// or fall back to raw strings if the string contains a `"` (false).
250
    ///
251
    /// When `true`, `"a\nb"` will serialize to
252
    /// ```
253
    /// "a\nb"
254
    /// # ;
255
    /// ```
256
    /// When `false`, `"a\nb"` will instead serialize to
257
    /// ```
258
    /// "a
259
    /// b"
260
    /// # ;
261
    /// ```
262
    ///
263
    /// Default: `true`
264
    #[must_use]
265
5580
    pub fn escape_strings(mut self, escape_strings: bool) -> Self {
266
5580
        self.escape_strings = escape_strings;
267

            
268
5580
        self
269
5580
    }
270

            
271
    /// Configures whether every struct should be a single line (`true`)
272
    /// or a multi line one (`false`).
273
    ///
274
    /// When `false`, `Struct { a: 4, b: 2 }` will serialize to
275
    /// ```ignore
276
    /// Struct(
277
    ///     a: 4,
278
    ///     b: 2,
279
    /// )
280
    /// # ;
281
    /// ```
282
    /// When `true`, `Struct { a: 4, b: 2 }` will instead serialize to
283
    /// ```ignore
284
    /// Struct(a: 4, b: 2)
285
    /// # ;
286
    /// ```
287
    ///
288
    /// Default: `false`
289
    #[must_use]
290
2270
    pub fn compact_structs(mut self, compact_structs: bool) -> Self {
291
2270
        self.compact_structs = compact_structs;
292

            
293
2270
        self
294
2270
    }
295

            
296
    /// Configures whether every map should be a single line (`true`)
297
    /// or a multi line one (`false`).
298
    ///
299
    /// When `false`, a map with entries `{ "a": 4, "b": 2 }` will serialize to
300
    /// ```ignore
301
    /// {
302
    ///     "a": 4,
303
    ///     "b": 2,
304
    /// }
305
    /// # ;
306
    /// ```
307
    /// When `true`, a map with entries `{ "a": 4, "b": 2 }` will instead
308
    /// serialize to
309
    /// ```ignore
310
    /// {"a": 4, "b": 2}
311
    /// # ;
312
    /// ```
313
    ///
314
    /// Default: `false`
315
    #[must_use]
316
310
    pub fn compact_maps(mut self, compact_maps: bool) -> Self {
317
310
        self.compact_maps = compact_maps;
318

            
319
310
        self
320
310
    }
321

            
322
    /// Configures whether numbers should be printed without (`false`) or
323
    /// with (`true`) their explicit type suffixes.
324
    ///
325
    /// When `false`, the integer `12345u16` will serialize to
326
    /// ```ignore
327
    /// 12345
328
    /// # ;
329
    /// ```
330
    /// and the float `12345.6789f64` will serialize to
331
    /// ```ignore
332
    /// 12345.6789
333
    /// # ;
334
    /// ```
335
    /// When `true`, the integer `12345u16` will serialize to
336
    /// ```ignore
337
    /// 12345u16
338
    /// # ;
339
    /// ```
340
    /// and the float `12345.6789f64` will serialize to
341
    /// ```ignore
342
    /// 12345.6789f64
343
    /// # ;
344
    /// ```
345
    ///
346
    /// Default: `false`
347
    #[must_use]
348
19220
    pub fn number_suffixes(mut self, number_suffixes: bool) -> Self {
349
19220
        self.number_suffixes = number_suffixes;
350

            
351
19220
        self
352
19220
    }
353

            
354
    /// Configures whether ranges should be serialized using compact syntax (`true`)
355
    /// or as regular structs (`false`).
356
    ///
357
    /// Note: compact range syntax is only used when the range bounds are numeric
358
    /// values. If the bounds are non-numeric, the range will fall back to the
359
    /// regular struct representation regardless of this setting.
360
    ///
361
    /// When `false`, `0..5` will serialize to
362
    /// ```ignore
363
    /// (
364
    ///     start: 0,
365
    ///     end: 5,
366
    /// )
367
    /// # ;
368
    /// ```
369
    /// When `true`, `0..5` will instead serialize to
370
    /// ```ignore
371
    /// 0..5
372
    /// # ;
373
    /// ```
374
    /// and `1..=3` will serialize to
375
    /// ```ignore
376
    /// 1..=3
377
    /// # ;
378
    /// ```
379
    ///
380
    /// Default: `false`
381
    #[must_use]
382
1860
    pub fn compact_ranges(mut self, compact_ranges: bool) -> Self {
383
1860
        self.compact_ranges = compact_ranges;
384
1860
        self
385
1860
    }
386
}
387

            
388
impl Default for PrettyConfig {
389
81320
    fn default() -> Self {
390
        PrettyConfig {
391
            depth_limit: usize::MAX,
392
81320
            new_line: if cfg!(not(target_os = "windows")) {
393
81320
                Cow::Borrowed("\n")
394
            } else {
395
                Cow::Borrowed("\r\n") // GRCOV_EXCL_LINE
396
            },
397
81320
            indentor: Cow::Borrowed("    "),
398
81320
            separator: Cow::Borrowed(" "),
399
            struct_names: false,
400
            separate_tuple_members: false,
401
            enumerate_arrays: false,
402
81320
            extensions: Extensions::empty(),
403
            compact_arrays: false,
404
            escape_strings: true,
405
            compact_structs: false,
406
            compact_maps: false,
407
            number_suffixes: false,
408
81320
            path_meta: None,
409
            compact_ranges: false,
410
        }
411
81320
    }
412
}
413

            
414
/// The RON serializer.
415
///
416
/// You can just use [`to_string`] for serializing a value.
417
/// If you want it pretty-printed, take a look at [`to_string_pretty`].
418
pub 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
    // Tracks the number of opened implicit `Some`s, set to 0 on backtracking
426
    implicit_some_depth: usize,
427
}
428

            
429
2284
fn indent<W: fmt::Write>(output: &mut W, config: &PrettyConfig, pretty: &Pretty) -> fmt::Result {
430
2284
    if pretty.indent <= config.depth_limit {
431
2236
        for _ in 0..pretty.indent {
432
3132
            output.write_str(&config.indentor)?;
433
        }
434
48
    }
435
2284
    Ok(())
436
2284
}
437

            
438
impl<W: fmt::Write> Serializer<W> {
439
    /// Creates a new [`Serializer`].
440
    ///
441
    /// Most of the time you can just use [`to_string`] or
442
    /// [`to_string_pretty`].
443
12
    pub fn new(writer: W, config: Option<PrettyConfig>) -> Result<Self> {
444
12
        Self::with_options(writer, config, &Options::default())
445
12
    }
446

            
447
    /// Creates a new [`Serializer`].
448
    ///
449
    /// Most of the time you can just use [`to_string`] or
450
    /// [`to_string_pretty`].
451
4072
    pub fn with_options(
452
4072
        mut writer: W,
453
4072
        config: Option<PrettyConfig>,
454
4072
        options: &Options,
455
4072
    ) -> Result<Self> {
456
4072
        if let Some(conf) = &config {
457
1876
            if !conf.new_line.chars().all(is_whitespace_char) {
458
4
                return Err(Error::Message(String::from(
459
4
                    "Invalid non-whitespace `PrettyConfig::new_line`",
460
4
                )));
461
1872
            }
462
1872
            if !conf.indentor.chars().all(is_whitespace_char) {
463
4
                return Err(Error::Message(String::from(
464
4
                    "Invalid non-whitespace `PrettyConfig::indentor`",
465
4
                )));
466
1868
            }
467
1868
            if !conf.separator.chars().all(is_whitespace_char) {
468
4
                return Err(Error::Message(String::from(
469
4
                    "Invalid non-whitespace `PrettyConfig::separator`",
470
4
                )));
471
1864
            }
472

            
473
1864
            let non_default_extensions = !options.default_extensions;
474

            
475
1876
            for (extension_name, _) in (non_default_extensions & conf.extensions).iter_names() {
476
196
                write!(writer, "#![enable({})]", extension_name.to_lowercase())?;
477
196
                writer.write_str(&conf.new_line)?;
478
            }
479
2196
        };
480
        Ok(Serializer {
481
4060
            output: writer,
482
4060
            pretty: config.map(|conf| (conf, Pretty { indent: 0 })),
483
4060
            default_extensions: options.default_extensions,
484
4060
            is_empty: None,
485
            newtype_variant: false,
486
4060
            recursion_limit: options.recursion_limit,
487
            implicit_some_depth: 0,
488
        })
489
4072
    }
490

            
491
    /// Unwrap the `Writer` from the `Serializer`.
492
    #[inline]
493
    pub fn into_inner(self) -> W {
494
        self.output
495
    }
496

            
497
2332
    fn separate_tuple_members(&self) -> bool {
498
2332
        self.pretty
499
2332
            .as_ref()
500
2332
            .map_or(false, |(ref config, _)| config.separate_tuple_members)
501
2332
    }
502

            
503
5552
    fn compact_arrays(&self) -> bool {
504
5552
        self.pretty
505
5552
            .as_ref()
506
5552
            .map_or(false, |(ref config, _)| config.compact_arrays)
507
5552
    }
508

            
509
4318
    fn compact_structs(&self) -> bool {
510
4318
        self.pretty
511
4318
            .as_ref()
512
4318
            .map_or(false, |(ref config, _)| config.compact_structs)
513
4318
    }
514

            
515
1596
    fn compact_maps(&self) -> bool {
516
1596
        self.pretty
517
1596
            .as_ref()
518
1596
            .map_or(false, |(ref config, _)| config.compact_maps)
519
1596
    }
520

            
521
3906
    fn number_suffixes(&self) -> bool {
522
3906
        self.pretty
523
3906
            .as_ref()
524
3906
            .map_or(false, |(ref config, _)| config.number_suffixes)
525
3906
    }
526

            
527
1308
    fn compact_ranges(&self) -> bool {
528
1308
        self.pretty
529
1308
            .as_ref()
530
1308
            .map_or(false, |(ref config, _)| config.compact_ranges)
531
1308
    }
532

            
533
3084
    fn extensions(&self) -> Extensions {
534
3084
        self.default_extensions
535
3084
            | self
536
3084
                .pretty
537
3084
                .as_ref()
538
3084
                .map_or(Extensions::empty(), |(ref config, _)| config.extensions)
539
3084
    }
540

            
541
1392
    fn escape_strings(&self) -> bool {
542
1392
        self.pretty
543
1392
            .as_ref()
544
1392
            .map_or(true, |(ref config, _)| config.escape_strings)
545
1392
    }
546

            
547
3628
    fn start_indent(&mut self) -> Result<()> {
548
3628
        if let Some((ref config, ref mut pretty)) = self.pretty {
549
1076
            pretty.indent += 1;
550
1076
            if pretty.indent <= config.depth_limit {
551
1052
                let is_empty = self.is_empty.unwrap_or(false);
552

            
553
1052
                if !is_empty {
554
1004
                    self.output.write_str(&config.new_line)?;
555
48
                }
556
24
            }
557
2552
        }
558
3628
        Ok(())
559
3628
    }
560

            
561
3284
    fn indent(&mut self) -> fmt::Result {
562
3284
        if let Some((ref config, ref pretty)) = self.pretty {
563
1124
            indent(&mut self.output, config, pretty)?;
564
2160
        }
565
3284
        Ok(())
566
3284
    }
567

            
568
2306
    fn end_indent(&mut self) -> fmt::Result {
569
2306
        if let Some((ref config, ref mut pretty)) = self.pretty {
570
1054
            if pretty.indent <= config.depth_limit {
571
1030
                let is_empty = self.is_empty.unwrap_or(false);
572

            
573
1030
                if !is_empty {
574
982
                    for _ in 1..pretty.indent {
575
458
                        self.output.write_str(&config.indentor)?;
576
                    }
577
48
                }
578
24
            }
579
1054
            pretty.indent -= 1;
580

            
581
1054
            self.is_empty = None;
582
1252
        }
583
2306
        Ok(())
584
2306
    }
585

            
586
1188
    fn serialize_escaped_str(&mut self, value: &str) -> fmt::Result {
587
1188
        self.output.write_char('"')?;
588
1188
        let mut scalar = [0u8; 4];
589
8008
        for c in value.chars().flat_map(char::escape_debug) {
590
7996
            self.output.write_str(c.encode_utf8(&mut scalar))?;
591
        }
592
1188
        self.output.write_char('"')?;
593
1188
        Ok(())
594
1188
    }
595

            
596
44
    fn serialize_unescaped_or_raw_str(&mut self, value: &str) -> fmt::Result {
597
44
        if value.contains('"') || value.contains('\\') {
598
32
            let (_, num_consecutive_hashes) =
599
368
                value.chars().fold((0, 0), |(count, max), c| match c {
600
24
                    '#' => (count + 1, max.max(count + 1)),
601
344
                    _ => (0_usize, max),
602
368
                });
603
32
            let hashes: String = "#".repeat(num_consecutive_hashes + 1);
604
32
            self.output.write_char('r')?;
605
32
            self.output.write_str(&hashes)?;
606
32
            self.output.write_char('"')?;
607
32
            self.output.write_str(value)?;
608
32
            self.output.write_char('"')?;
609
32
            self.output.write_str(&hashes)?;
610
        } else {
611
12
            self.output.write_char('"')?;
612
12
            self.output.write_str(value)?;
613
12
            self.output.write_char('"')?;
614
        }
615
44
        Ok(())
616
44
    }
617

            
618
136
    fn serialize_escaped_byte_str(&mut self, value: &[u8]) -> fmt::Result {
619
136
        self.output.write_str("b\"")?;
620
5356
        for c in value.iter().flat_map(|c| core::ascii::escape_default(*c)) {
621
5356
            self.output.write_char(char::from(c))?;
622
        }
623
136
        self.output.write_char('"')?;
624
136
        Ok(())
625
136
    }
626

            
627
24
    fn serialize_unescaped_or_raw_byte_str(&mut self, value: &str) -> fmt::Result {
628
24
        if value.contains('"') || value.contains('\\') {
629
12
            let (_, num_consecutive_hashes) =
630
16
                value.chars().fold((0, 0), |(count, max), c| match c {
631
4
                    '#' => (count + 1, max.max(count + 1)),
632
12
                    _ => (0_usize, max),
633
16
                });
634
12
            let hashes: String = "#".repeat(num_consecutive_hashes + 1);
635
12
            self.output.write_str("br")?;
636
12
            self.output.write_str(&hashes)?;
637
12
            self.output.write_char('"')?;
638
12
            self.output.write_str(value)?;
639
12
            self.output.write_char('"')?;
640
12
            self.output.write_str(&hashes)?;
641
        } else {
642
12
            self.output.write_str("b\"")?;
643
12
            self.output.write_str(value)?;
644
12
            self.output.write_char('"')?;
645
        }
646
24
        Ok(())
647
24
    }
648

            
649
1648
    fn serialize_sint(&mut self, value: impl Into<LargeSInt>, suffix: &str) -> Result<()> {
650
        // TODO optimize
651
1648
        write!(self.output, "{}", value.into())?;
652

            
653
1648
        if self.number_suffixes() {
654
72
            write!(self.output, "{}", suffix)?;
655
1576
        }
656

            
657
1648
        Ok(())
658
1648
    }
659

            
660
1318
    fn serialize_uint(&mut self, value: impl Into<LargeUInt>, suffix: &str) -> Result<()> {
661
        // TODO optimize
662
1318
        write!(self.output, "{}", value.into())?;
663

            
664
1318
        if self.number_suffixes() {
665
72
            write!(self.output, "{}", suffix)?;
666
1246
        }
667

            
668
1318
        Ok(())
669
1318
    }
670

            
671
3080
    fn write_identifier(&mut self, name: &str) -> Result<()> {
672
3080
        self.validate_identifier(name)?;
673
3048
        let mut chars = name.chars();
674
3048
        if !chars.next().map_or(false, is_ident_first_char)
675
3028
            || !chars.all(is_xid_continue)
676
2984
            || [
677
2984
                "true", "false", "Some", "None", "inf", "inff32", "inff64", "NaN", "NaNf32",
678
2984
                "NaNf64",
679
2984
            ]
680
2984
            .contains(&name)
681
        {
682
104
            self.output.write_str("r#")?;
683
2944
        }
684
3048
        self.output.write_str(name)?;
685
3048
        Ok(())
686
3080
    }
687

            
688
    #[allow(clippy::unused_self)]
689
5328
    fn validate_identifier(&self, name: &str) -> Result<()> {
690
5328
        if name.is_empty() || !name.chars().all(is_ident_raw_char) {
691
60
            return Err(Error::InvalidIdentifier(name.into()));
692
5268
        }
693
5268
        Ok(())
694
5328
    }
695

            
696
    /// Checks if struct names should be emitted
697
    ///
698
    /// 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.
699
1528
    fn struct_names(&self) -> bool {
700
1528
        self.extensions()
701
1528
            .contains(Extensions::EXPLICIT_STRUCT_NAMES)
702
1512
            || self
703
1512
                .pretty
704
1512
                .as_ref()
705
1512
                .map_or(false, |(pc, _)| pc.struct_names)
706
1528
    }
707
}
708

            
709
macro_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

            
729
impl<'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
412
    fn serialize_bool(self, v: bool) -> Result<()> {
741
412
        self.output.write_str(if v { "true" } else { "false" })?;
742
412
        Ok(())
743
412
    }
744

            
745
136
    fn serialize_i8(self, v: i8) -> Result<()> {
746
136
        self.serialize_sint(v, "i8")
747
136
    }
748

            
749
84
    fn serialize_i16(self, v: i16) -> Result<()> {
750
84
        self.serialize_sint(v, "i16")
751
84
    }
752

            
753
1284
    fn serialize_i32(self, v: i32) -> Result<()> {
754
1284
        self.serialize_sint(v, "i32")
755
1284
    }
756

            
757
92
    fn serialize_i64(self, v: i64) -> Result<()> {
758
92
        self.serialize_sint(v, "i64")
759
92
    }
760

            
761
    #[cfg(feature = "integer128")]
762
52
    fn serialize_i128(self, v: i128) -> Result<()> {
763
52
        self.serialize_sint(v, "i128")
764
52
    }
765

            
766
616
    fn serialize_u8(self, v: u8) -> Result<()> {
767
616
        self.serialize_uint(v, "u8")
768
616
    }
769

            
770
84
    fn serialize_u16(self, v: u16) -> Result<()> {
771
84
        self.serialize_uint(v, "u16")
772
84
    }
773

            
774
448
    fn serialize_u32(self, v: u32) -> Result<()> {
775
448
        self.serialize_uint(v, "u32")
776
448
    }
777

            
778
120
    fn serialize_u64(self, v: u64) -> Result<()> {
779
120
        self.serialize_uint(v, "u64")
780
120
    }
781

            
782
    #[cfg(feature = "integer128")]
783
50
    fn serialize_u128(self, v: u128) -> Result<()> {
784
50
        self.serialize_uint(v, "u128")
785
50
    }
786

            
787
596
    fn serialize_f32(self, v: f32) -> Result<()> {
788
596
        if v.is_nan() && v.is_sign_negative() {
789
48
            write!(self.output, "-")?;
790
548
        }
791

            
792
        // `Debug` emits the shortest representation that round-trips, using
793
        // exponent notation for very large or small magnitudes (e.g. `1e300`)
794
        // and always including a `.0` or exponent for finite values, so they
795
        // are never parsed back as integers.
796
596
        write!(self.output, "{:?}", v)?;
797

            
798
596
        if self.number_suffixes() {
799
60
            write!(self.output, "f32")?;
800
536
        }
801

            
802
596
        Ok(())
803
596
    }
804

            
805
344
    fn serialize_f64(self, v: f64) -> Result<()> {
806
344
        if v.is_nan() && v.is_sign_negative() {
807
16
            write!(self.output, "-")?;
808
328
        }
809

            
810
        // `Debug` emits the shortest representation that round-trips, using
811
        // exponent notation for very large or small magnitudes (e.g. `1e300`)
812
        // and always including a `.0` or exponent for finite values, so they
813
        // are never parsed back as integers.
814
344
        write!(self.output, "{:?}", v)?;
815

            
816
344
        if self.number_suffixes() {
817
60
            write!(self.output, "f64")?;
818
284
        }
819

            
820
344
        Ok(())
821
344
    }
822

            
823
676
    fn serialize_char(self, v: char) -> Result<()> {
824
676
        self.output.write_char('\'')?;
825
676
        if v == '\\' || v == '\'' {
826
36
            self.output.write_char('\\')?;
827
640
        }
828
676
        write!(self.output, "{}", v)?;
829
676
        self.output.write_char('\'')?;
830
676
        Ok(())
831
676
    }
832

            
833
1232
    fn serialize_str(self, v: &str) -> Result<()> {
834
1232
        if self.escape_strings() {
835
1188
            self.serialize_escaped_str(v)?;
836
        } else {
837
44
            self.serialize_unescaped_or_raw_str(v)?;
838
        }
839

            
840
1232
        Ok(())
841
1232
    }
842

            
843
160
    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
844
        // We need to fall back to escaping if the byte string would be invalid UTF-8
845
160
        if !self.escape_strings() {
846
28
            if let Ok(v) = core::str::from_utf8(v) {
847
24
                return self
848
24
                    .serialize_unescaped_or_raw_byte_str(v)
849
24
                    .map_err(Error::from);
850
4
            }
851
132
        }
852

            
853
136
        self.serialize_escaped_byte_str(v)?;
854

            
855
136
        Ok(())
856
160
    }
857

            
858
76
    fn serialize_none(self) -> Result<()> {
859
        // We no longer need to keep track of the depth
860
76
        let implicit_some_depth = self.implicit_some_depth;
861
76
        self.implicit_some_depth = 0;
862

            
863
76
        for _ in 0..implicit_some_depth {
864
12
            self.output.write_str("Some(")?;
865
        }
866
76
        self.output.write_str("None")?;
867
76
        for _ in 0..implicit_some_depth {
868
12
            self.output.write_char(')')?;
869
        }
870

            
871
76
        Ok(())
872
76
    }
873

            
874
532
    fn serialize_some<T>(self, value: &T) -> Result<()>
875
532
    where
876
532
        T: ?Sized + Serialize,
877
    {
878
532
        let implicit_some = self.extensions().contains(Extensions::IMPLICIT_SOME);
879
532
        if implicit_some {
880
120
            self.implicit_some_depth += 1;
881
120
        } else {
882
412
            self.newtype_variant = self
883
412
                .extensions()
884
412
                .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
885
412
            self.output.write_str("Some(")?;
886
        }
887
532
        guard_recursion! { self => value.serialize(&mut *self)? };
888
276
        if implicit_some {
889
120
            self.implicit_some_depth = 0;
890
120
        } else {
891
156
            self.output.write_char(')')?;
892
156
            self.newtype_variant = false;
893
        }
894

            
895
276
        Ok(())
896
532
    }
897

            
898
228
    fn serialize_unit(self) -> Result<()> {
899
228
        if !self.newtype_variant {
900
224
            self.output.write_str("()")?;
901
4
        }
902

            
903
228
        Ok(())
904
228
    }
905

            
906
96
    fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
907
96
        if self.compact_ranges() && name == "RangeFull" {
908
4
            self.output.write_str("..")?;
909
4
            return Ok(());
910
92
        }
911

            
912
92
        if self.struct_names() && !self.newtype_variant {
913
16
            self.write_identifier(name)?;
914

            
915
8
            Ok(())
916
        } else {
917
76
            self.validate_identifier(name)?;
918
76
            self.serialize_unit()
919
        }
920
96
    }
921

            
922
240
    fn serialize_unit_variant(
923
240
        self,
924
240
        name: &'static str,
925
240
        _variant_index: u32,
926
240
        variant: &'static str,
927
240
    ) -> Result<()> {
928
240
        self.validate_identifier(name)?;
929
236
        self.write_identifier(variant)?;
930

            
931
232
        Ok(())
932
240
    }
933

            
934
476
    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
935
476
    where
936
476
        T: ?Sized + Serialize,
937
    {
938
476
        if name == crate::value::raw::RAW_VALUE_TOKEN {
939
228
            let implicit_some_depth = self.implicit_some_depth;
940
228
            self.implicit_some_depth = 0;
941

            
942
228
            for _ in 0..implicit_some_depth {
943
8
                self.output.write_str("Some(")?;
944
            }
945

            
946
228
            guard_recursion! { self => value.serialize(raw::Serializer::new(self)) }?;
947

            
948
116
            for _ in 0..implicit_some_depth {
949
8
                self.output.write_char(')')?;
950
            }
951

            
952
116
            return Ok(());
953
248
        }
954

            
955
248
        if self.extensions().contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
956
40
            self.newtype_variant = false;
957

            
958
40
            self.validate_identifier(name)?;
959

            
960
40
            return guard_recursion! { self => value.serialize(&mut *self) };
961
208
        }
962

            
963
208
        if self.struct_names() {
964
12
            self.write_identifier(name)?;
965
        } else {
966
196
            self.validate_identifier(name)?;
967
        }
968

            
969
204
        self.implicit_some_depth = 0;
970

            
971
204
        self.output.write_char('(')?;
972
204
        guard_recursion! { self => value.serialize(&mut *self)? };
973
204
        self.output.write_char(')')?;
974

            
975
204
        Ok(())
976
476
    }
977

            
978
372
    fn serialize_newtype_variant<T>(
979
372
        self,
980
372
        name: &'static str,
981
372
        _variant_index: u32,
982
372
        variant: &'static str,
983
372
        value: &T,
984
372
    ) -> Result<()>
985
372
    where
986
372
        T: ?Sized + Serialize,
987
    {
988
372
        self.validate_identifier(name)?;
989
368
        self.write_identifier(variant)?;
990
364
        self.output.write_char('(')?;
991

            
992
364
        self.newtype_variant = self
993
364
            .extensions()
994
364
            .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
995
364
        self.implicit_some_depth = 0;
996

            
997
364
        guard_recursion! { self => value.serialize(&mut *self)? };
998

            
999
362
        self.newtype_variant = false;
362
        self.output.write_char(')')?;
362
        Ok(())
372
    }
2072
    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
2072
        self.newtype_variant = false;
2072
        self.implicit_some_depth = 0;
2072
        self.output.write_char('[')?;
2072
        if !self.compact_arrays() {
2044
            if let Some(len) = len {
2044
                self.is_empty = Some(len == 0);
2044
            }
2044
            self.start_indent()?;
28
        }
2072
        Ok(Compound::new(self, false))
2072
    }
352
    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
352
        let old_newtype_variant = self.newtype_variant;
352
        self.newtype_variant = false;
352
        self.implicit_some_depth = 0;
352
        if !old_newtype_variant {
324
            self.output.write_char('(')?;
28
        }
352
        if self.separate_tuple_members() {
32
            self.is_empty = Some(len == 0);
32
            self.start_indent()?;
320
        }
352
        Ok(Compound::new(self, old_newtype_variant))
352
    }
104
    fn serialize_tuple_struct(
104
        self,
104
        name: &'static str,
104
        len: usize,
104
    ) -> Result<Self::SerializeTupleStruct> {
104
        if self.struct_names() && !self.newtype_variant {
20
            self.write_identifier(name)?;
        } else {
84
            self.validate_identifier(name)?;
        }
100
        self.serialize_tuple(len)
104
    }
100
    fn serialize_tuple_variant(
100
        self,
100
        name: &'static str,
100
        _variant_index: u32,
100
        variant: &'static str,
100
        len: usize,
100
    ) -> Result<Self::SerializeTupleVariant> {
100
        self.newtype_variant = false;
100
        self.implicit_some_depth = 0;
100
        self.validate_identifier(name)?;
96
        self.write_identifier(variant)?;
92
        self.output.write_char('(')?;
92
        if self.separate_tuple_members() {
8
            self.is_empty = Some(len == 0);
8
            self.start_indent()?;
84
        }
92
        Ok(Compound::new(self, false))
100
    }
384
    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
384
        self.newtype_variant = false;
384
        self.implicit_some_depth = 0;
384
        self.output.write_char('{')?;
384
        if !self.compact_maps() {
380
            if let Some(len) = len {
120
                self.is_empty = Some(len == 0);
364
            }
380
            self.start_indent()?;
4
        }
384
        Ok(Compound::new(self, false))
384
    }
1212
    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
1212
        let old_newtype_variant = self.newtype_variant;
1212
        if self.compact_ranges()
92
            && ((len == 2 && (name == "Range" || name == "RangeInclusive"))
36
                || (len == 1
28
                    && (name == "RangeFrom" || name == "RangeTo" || name == "RangeToInclusive")))
        {
84
            self.newtype_variant = false;
84
            self.implicit_some_depth = 0;
84
            return Ok(Compound::new_range(
84
                self,
84
                name,
84
                old_newtype_variant,
84
                if name == "RangeInclusive" {
16
                    RangeKind::RangeInclusive
68
                } else if name == "RangeFrom" {
8
                    RangeKind::RangeFrom
60
                } else if name == "RangeTo" {
12
                    RangeKind::RangeTo
48
                } else if name == "RangeToInclusive" {
8
                    RangeKind::RangeToInclusive
                } else {
40
                    RangeKind::Range
                },
            ));
1128
        }
1128
        self.newtype_variant = false;
1128
        self.implicit_some_depth = 0;
1128
        if old_newtype_variant {
16
            self.validate_identifier(name)?;
        } else {
1112
            if self.struct_names() {
72
                self.write_identifier(name)?;
            } else {
1040
                self.validate_identifier(name)?;
            }
1108
            self.output.write_char('(')?;
        }
1124
        if !self.compact_structs() {
1096
            self.is_empty = Some(len == 0);
1096
            self.start_indent()?;
28
        }
1124
        Ok(Compound::new(self, old_newtype_variant))
1212
    }
84
    fn serialize_struct_variant(
84
        self,
84
        name: &'static str,
84
        _variant_index: u32,
84
        variant: &'static str,
84
        len: usize,
84
    ) -> Result<Self::SerializeStructVariant> {
84
        self.newtype_variant = false;
84
        self.implicit_some_depth = 0;
84
        self.validate_identifier(name)?;
80
        self.write_identifier(variant)?;
76
        self.output.write_char('(')?;
76
        if !self.compact_structs() {
68
            self.is_empty = Some(len == 0);
68
            self.start_indent()?;
8
        }
76
        Ok(Compound::new(self, false))
84
    }
}
enum State {
    First,
    Rest,
}
#[doc(hidden)]
pub struct Compound<'a, W: fmt::Write> {
    ser: &'a mut Serializer<W>,
    state: State,
    newtype_variant: bool,
    sequence_index: usize,
    range: Option<RangeCompound>,
}
impl<'a, W: fmt::Write> Compound<'a, W> {
4100
    fn new(ser: &'a mut Serializer<W>, newtype_variant: bool) -> Self {
4100
        Compound {
4100
            ser,
4100
            state: State::First,
4100
            newtype_variant,
4100
            sequence_index: 0,
4100
            range: None,
4100
        }
4100
    }
84
    fn new_range(
84
        ser: &'a mut Serializer<W>,
84
        name: &'static str,
84
        newtype_variant: bool,
84
        kind: RangeKind,
84
    ) -> Self {
84
        Compound {
84
            ser,
84
            state: State::First,
84
            newtype_variant: false,
84
            sequence_index: 0,
84
            range: Some(RangeCompound::new(name, newtype_variant, kind)),
84
        }
84
    }
}
enum RangeKind {
    Range,
    RangeInclusive,
    RangeFrom,
    RangeTo,
    RangeToInclusive,
}
struct RangeCompound {
    name: &'static str,
    // Whether the range is the content of an unwrapped newtype variant, which
    // the struct form fallback must then write without its own parentheses.
    newtype_variant: bool,
    kind: RangeKind,
    // Stores (field_key, number) so the actual key is preserved through fallback replay.
    first: Option<(&'static str, crate::value::Number)>,
    second: Option<(&'static str, crate::value::Number)>,
    fallback: bool,
}
impl RangeCompound {
6510
    fn new(name: &'static str, newtype_variant: bool, kind: RangeKind) -> Self {
6510
        RangeCompound {
6510
            name,
6510
            newtype_variant,
6510
            kind,
6510
            first: None,
6510
            second: None,
6510
            fallback: false,
6510
        }
6510
    }
    /// Try to serialize `value` as a number into a String buffer.
    /// Returns `Some(s)` if numeric, `None` otherwise.
124
    fn try_serialize_number<T>(value: &T) -> Option<crate::value::Number>
124
    where
124
        T: ?Sized + Serialize,
    {
124
        value.serialize(crate::value::NumberSerializer).ok()
124
    }
}
impl<'a, W: fmt::Write> ser::SerializeSeq for Compound<'a, W> {
    type Error = Error;
    type Ok = ();
2440
    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
2440
    where
2440
        T: ?Sized + Serialize,
    {
2440
        if let State::First = self.state {
1236
            self.state = State::Rest;
1236
        } else {
1204
            self.ser.output.write_char(',')?;
1204
            if let Some((ref config, ref mut pretty)) = self.ser.pretty {
224
                if pretty.indent <= config.depth_limit && !config.compact_arrays {
176
                    self.ser.output.write_str(&config.new_line)?;
                } else {
48
                    self.ser.output.write_str(&config.separator)?;
                }
980
            }
        }
2440
        if !self.ser.compact_arrays() {
2376
            self.ser.indent()?;
64
        }
2440
        if let Some((ref mut config, ref mut pretty)) = self.ser.pretty {
348
            if pretty.indent <= config.depth_limit && config.enumerate_arrays {
72
                write!(self.ser.output, "/*[{}]*/ ", self.sequence_index)?;
72
                self.sequence_index += 1;
276
            }
2092
        }
2440
        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1408
        Ok(())
2440
    }
1040
    fn end(self) -> Result<()> {
1040
        if let State::Rest = self.state {
204
            if let Some((ref config, ref mut pretty)) = self.ser.pretty {
124
                if pretty.indent <= config.depth_limit && !config.compact_arrays {
96
                    self.ser.output.write_char(',')?;
96
                    self.ser.output.write_str(&config.new_line)?;
28
                }
80
            }
836
        }
1040
        if !self.ser.compact_arrays() {
1012
            self.ser.end_indent()?;
28
        }
        // seq always disables `self.newtype_variant`
1040
        self.ser.output.write_char(']')?;
1040
        Ok(())
1040
    }
}
impl<'a, W: fmt::Write> ser::SerializeTuple for Compound<'a, W> {
    type Error = Error;
    type Ok = ();
952
    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
952
    where
952
        T: ?Sized + Serialize,
    {
952
        if let State::First = self.state {
396
            self.state = State::Rest;
396
        } else {
556
            self.ser.output.write_char(',')?;
556
            if let Some((ref config, ref pretty)) = self.ser.pretty {
292
                if pretty.indent <= config.depth_limit && self.ser.separate_tuple_members() {
32
                    self.ser.output.write_str(&config.new_line)?;
                } else {
260
                    self.ser.output.write_str(&config.separator)?;
                }
264
            }
        }
952
        if self.ser.separate_tuple_members() {
84
            self.ser.indent()?;
868
        }
952
        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
940
        Ok(())
952
    }
432
    fn end(self) -> Result<()> {
432
        if let State::Rest = self.state {
384
            if let Some((ref config, ref pretty)) = self.ser.pretty {
224
                if self.ser.separate_tuple_members() && pretty.indent <= config.depth_limit {
28
                    self.ser.output.write_char(',')?;
28
                    self.ser.output.write_str(&config.new_line)?;
196
                }
160
            }
48
        }
432
        if self.ser.separate_tuple_members() {
40
            self.ser.end_indent()?;
392
        }
432
        if !self.newtype_variant {
404
            self.ser.output.write_char(')')?;
28
        }
432
        Ok(())
432
    }
}
// Same thing but for tuple structs.
impl<'a, W: fmt::Write> ser::SerializeTupleStruct for Compound<'a, W> {
    type Error = Error;
    type Ok = ();
168
    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
168
    where
168
        T: ?Sized + Serialize,
    {
168
        ser::SerializeTuple::serialize_element(self, value)
168
    }
100
    fn end(self) -> Result<()> {
100
        ser::SerializeTuple::end(self)
100
    }
}
impl<'a, W: fmt::Write> ser::SerializeTupleVariant for Compound<'a, W> {
    type Error = Error;
    type Ok = ();
156
    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
156
    where
156
        T: ?Sized + Serialize,
    {
156
        ser::SerializeTuple::serialize_element(self, value)
156
    }
92
    fn end(self) -> Result<()> {
92
        ser::SerializeTuple::end(self)
92
    }
}
impl<'a, W: fmt::Write> ser::SerializeMap for Compound<'a, W> {
    type Error = Error;
    type Ok = ();
832
    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
832
    where
832
        T: ?Sized + Serialize,
    {
832
        if let State::First = self.state {
360
            self.state = State::Rest;
360
        } else {
472
            self.ser.output.write_char(',')?;
472
            if let Some((ref config, ref pretty)) = self.ser.pretty {
432
                if pretty.indent <= config.depth_limit && !config.compact_maps {
428
                    self.ser.output.write_str(&config.new_line)?;
                } else {
4
                    self.ser.output.write_str(&config.separator)?;
                }
40
            }
        }
832
        if !self.ser.compact_maps() {
824
            self.ser.indent()?;
8
        }
832
        guard_recursion! { self.ser => key.serialize(&mut *self.ser) }
832
    }
832
    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
832
    where
832
        T: ?Sized + Serialize,
    {
832
        self.ser.output.write_char(':')?;
832
        if let Some((ref config, _)) = self.ser.pretty {
764
            self.ser.output.write_str(&config.separator)?;
68
        }
832
        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
828
        Ok(())
832
    }
380
    fn end(self) -> Result<()> {
380
        if let State::Rest = self.state {
356
            if let Some((ref config, ref pretty)) = self.ser.pretty {
328
                if pretty.indent <= config.depth_limit && !config.compact_maps {
320
                    self.ser.output.write_char(',')?;
320
                    self.ser.output.write_str(&config.new_line)?;
8
                }
28
            }
24
        }
380
        if !self.ser.compact_maps() {
376
            self.ser.end_indent()?;
4
        }
        // map always disables `self.newtype_variant`
380
        self.ser.output.write_char('}')?;
380
        Ok(())
380
    }
}
impl<'a, W: fmt::Write> ser::SerializeStruct for Compound<'a, W> {
    type Error = Error;
    type Ok = ();
    #[allow(clippy::too_many_lines)]
2280
    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
2280
    where
2280
        T: ?Sized + Serialize,
    {
2280
        if let Some(ref mut range) = self.range {
140
            if !range.fallback {
124
                match RangeCompound::try_serialize_number(value) {
108
                    Some(s) => {
                        // Validate that the field key matches what this range variant expects,
                        // and that we haven't received more fields than the variant allows.
108
                        let expected_key = match range.kind {
                            RangeKind::RangeTo | RangeKind::RangeToInclusive => {
20
                                if range.first.is_none() {
20
                                    "end"
                                } else {
                                    ""
                                }
                            }
                            _ => {
88
                                if range.first.is_none() {
48
                                    "start"
                                } else {
40
                                    "end"
                                }
                            }
                        };
108
                        let max_fields = match range.kind {
                            RangeKind::RangeFrom
                            | RangeKind::RangeTo
28
                            | RangeKind::RangeToInclusive => 1,
80
                            RangeKind::Range | RangeKind::RangeInclusive => 2,
                        };
108
                        if key != expected_key
108
                            || (range.first.is_some() && max_fields < 2)
108
                            || range.second.is_some()
                        {
                            range.fallback = true;
108
                        } else if range.first.is_none() {
68
                            // Store the actual key alongside the number so it is
68
                            // replayed correctly if we later fall back to struct form.
68
                            range.first = Some((key, s));
68
                        } else {
40
                            range.second = Some((key, s));
40
                        }
108
                        if !range.fallback {
108
                            return Ok(());
                        }
                    }
16
                    None => {
16
                        range.fallback = true;
16
                    }
                }
                // Write the struct opening as `serialize_struct` would have
16
                if range.newtype_variant {
4
                    self.newtype_variant = true;
4
                } else {
12
                    if self.ser.struct_names() {
8
                        self.ser.write_identifier(range.name)?;
4
                    }
12
                    self.ser.output.write_char('(')?;
                }
16
                if !self.ser.compact_structs() {
                    self.ser.is_empty = Some(false);
                    self.ser.start_indent()?;
16
                }
                // Replay any buffered numeric fields using their actual stored keys.
16
                let buffered: [Option<(&'static str, crate::value::Number)>; 2] =
16
                    [range.first.take(), range.second.take()];
16
                for (bkey, bval) in buffered.into_iter().flatten() {
                    ser::SerializeStruct::serialize_field(self, bkey, &bval)?;
                }
                // fall through to emit the current field normally
16
            }
2140
        }
2172
        let mut restore_field = self.ser.pretty.as_mut().and_then(|(config, _)| {
1192
            config.path_meta.take().map(|mut field| {
92
                if let Some(fields) = field.fields_mut() {
92
                    config.path_meta = fields.remove(key);
92
                }
92
                field
92
            })
1192
        });
2172
        if let State::First = self.state {
1188
            self.state = State::Rest;
1188
        } else {
984
            self.ser.output.write_char(',')?;
984
            if let Some((ref config, ref pretty)) = self.ser.pretty {
592
                if pretty.indent <= config.depth_limit && !config.compact_structs {
516
                    self.ser.output.write_str(&config.new_line)?;
                } else {
76
                    self.ser.output.write_str(&config.separator)?;
                }
392
            }
        }
2172
        if !self.ser.compact_structs() {
2056
            if let Some((ref config, ref pretty)) = self.ser.pretty {
1076
                indent(&mut self.ser.output, config, pretty)?;
1076
                if let Some(ref field) = config.path_meta {
84
                    for doc_line in field.doc().lines() {
84
                        self.ser.output.write_str("/// ")?;
84
                        self.ser.output.write_str(doc_line)?;
                        // A line comment only ends at `\n`, so a `new_line`
                        // without one (e.g. "") must not be used to close it
84
                        if config.new_line.contains('\n') {
72
                            self.ser.output.write_str(&config.new_line)?;
                        } else {
12
                            self.ser.output.write_char('\n')?;
                        }
84
                        indent(&mut self.ser.output, config, pretty)?;
                    }
1016
                }
980
            }
116
        }
2172
        self.ser.write_identifier(key)?;
2164
        self.ser.output.write_char(':')?;
2164
        if let Some((ref config, _)) = self.ser.pretty {
1192
            self.ser.output.write_str(&config.separator)?;
972
        }
2164
        guard_recursion! { self.ser => value.serialize(&mut *self.ser)? };
1886
        if let Some((ref mut config, _)) = self.ser.pretty {
1174
            core::mem::swap(&mut config.path_meta, &mut restore_field);
1174
            if let Some(ref mut field) = config.path_meta {
92
                if let Some(fields) = field.fields_mut() {
92
                    if let Some(restore_field) = restore_field {
60
                        fields.insert(key, restore_field);
60
                    }
                }
1082
            }
712
        };
1886
        Ok(())
2280
    }
998
    fn end(mut self) -> Result<()> {
998
        if let Some(ref mut range) = self.range {
84
            if !range.fallback {
                // All fields were numeric — emit compact syntax.
68
                let sep = match range.kind {
24
                    RangeKind::RangeInclusive | RangeKind::RangeToInclusive => "..=",
44
                    _ => "..",
                };
68
                match range.kind {
                    RangeKind::RangeFrom => {
8
                        if let Some((_, start)) = range.first.take() {
8
                            start.serialize(&mut *self.ser)?;
                        }
8
                        self.ser.output.write_str("..")?;
                    }
                    RangeKind::RangeTo | RangeKind::RangeToInclusive => {
20
                        self.ser.output.write_str(sep)?;
20
                        if let Some((_, end)) = range.first.take() {
20
                            end.serialize(&mut *self.ser)?;
                        }
                    }
                    RangeKind::Range | RangeKind::RangeInclusive => {
40
                        if let Some((_, start)) = range.first.take() {
40
                            start.serialize(&mut *self.ser)?;
                        }
40
                        self.ser.output.write_str(sep)?;
40
                        if let Some((_, end)) = range.second.take() {
40
                            end.serialize(&mut *self.ser)?;
                        }
                    }
                }
68
                return Ok(());
16
            }
            // fallback: close the struct normally (end_indent + ')' handled below)
914
        }
930
        if let State::Rest = self.state {
902
            if let Some((ref config, ref pretty)) = self.ser.pretty {
582
                if pretty.indent <= config.depth_limit && !config.compact_structs {
534
                    self.ser.output.write_char(',')?;
534
                    self.ser.output.write_str(&config.new_line)?;
48
                }
320
            }
28
        }
930
        if !self.ser.compact_structs() {
878
            self.ser.end_indent()?;
52
        }
930
        if !self.newtype_variant {
910
            self.ser.output.write_char(')')?;
20
        }
930
        Ok(())
998
    }
}
impl<'a, W: fmt::Write> ser::SerializeStructVariant for Compound<'a, W> {
    type Error = Error;
    type Ok = ();
152
    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
152
    where
152
        T: ?Sized + Serialize,
    {
152
        ser::SerializeStruct::serialize_field(self, key, value)
152
    }
72
    fn end(self) -> Result<()> {
72
        ser::SerializeStruct::end(self)
72
    }
}