1
#![allow(clippy::identity_op)]
2

            
3
use alloc::{
4
    format,
5
    string::{String, ToString},
6
    vec::Vec,
7
};
8
use core::{
9
    char::from_u32 as char_from_u32,
10
    str::{self, from_utf8, FromStr, Utf8Error},
11
};
12

            
13
use unicode_ident::{is_xid_continue, is_xid_start};
14

            
15
use crate::{
16
    error::{Error, Position, Result, Span, SpannedError, SpannedResult},
17
    extensions::Extensions,
18
    value::Number,
19
};
20

            
21
48233235
const fn is_int_char(c: char) -> bool {
22
48233235
    c.is_ascii_hexdigit() || c == '_'
23
48233235
}
24

            
25
183712024
const fn is_float_char(c: char) -> bool {
26
183712024
    c.is_ascii_digit() || matches!(c, 'e' | 'E' | '.' | '+' | '-' | '_')
27
183712024
}
28

            
29
10037077
pub fn is_ident_first_char(c: char) -> bool {
30
10037077
    c == '_' || is_xid_start(c)
31
10037077
}
32

            
33
4533606
pub fn is_ident_raw_char(c: char) -> bool {
34
4533606
    matches!(c, '.' | '+' | '-') | is_xid_continue(c)
35
4533606
}
36

            
37
33126560
pub const fn is_whitespace_char(c: char) -> bool {
38
30774680
    matches!(
39
33126560
        c,
40
        ' ' | '\t'
41
            | '\n'
42
            | '\r'
43
            | '\x0B'
44
            | '\x0C'
45
            | '\u{85}'
46
            | '\u{200E}'
47
            | '\u{200F}'
48
            | '\u{2028}'
49
            | '\u{2029}'
50
    )
51
33126560
}
52

            
53
#[cfg(feature = "integer128")]
54
pub(crate) type LargeUInt = u128;
55
#[cfg(not(feature = "integer128"))]
56
pub(crate) type LargeUInt = u64;
57
#[cfg(feature = "integer128")]
58
pub(crate) type LargeSInt = i128;
59
#[cfg(not(feature = "integer128"))]
60
pub(crate) type LargeSInt = i64;
61

            
62
pub struct Parser<'a> {
63
    /// Bits set according to the [`Extensions`] enum.
64
    pub exts: Extensions,
65
    src: &'a str,
66
    cursor: ParserCursor,
67
    prev_cursor: ParserCursor,
68
}
69

            
70
#[derive(Copy, Clone)] // GRCOV_EXCL_LINE
71
pub struct ParserCursor {
72
    cursor: usize,
73
    pre_ws_cursor: usize,
74
    last_ws_len: usize,
75
}
76

            
77
enum ParsedAttribute {
78
    None,
79
    Extensions(Extensions),
80
    Ignored,
81
}
82

            
83
const WS_CURSOR_UNCLOSED_LINE: usize = usize::MAX;
84

            
85
impl PartialEq for ParserCursor {
86
8
    fn eq(&self, other: &Self) -> bool {
87
8
        self.cursor == other.cursor
88
8
    }
89
}
90

            
91
impl PartialOrd for ParserCursor {
92
3572
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
93
3572
        self.cursor.partial_cmp(&other.cursor)
94
3572
    }
95
}
96

            
97
/// constructor and parsing utilities
98
impl<'a> Parser<'a> {
99
582376
    pub fn new(src: &'a str) -> SpannedResult<Self> {
100
582376
        let mut parser = Parser {
101
582376
            exts: Extensions::empty(),
102
582376
            src,
103
582376
            cursor: ParserCursor {
104
582376
                cursor: 0,
105
582376
                pre_ws_cursor: 0,
106
582376
                last_ws_len: 0,
107
582376
            },
108
582376
            prev_cursor: ParserCursor {
109
582376
                cursor: 0,
110
582376
                pre_ws_cursor: 0,
111
582376
                last_ws_len: 0,
112
582376
            },
113
582376
        };
114

            
115
582376
        parser.skip_ws().map_err(|e| parser.span_error(e))?;
116

            
117
        // Loop over all document attributes
118
        loop {
119
618434
            match parser.attribute().map_err(|e| parser.span_error(e))? {
120
581524
                ParsedAttribute::None => break,
121
36316
                ParsedAttribute::Extensions(extensions) => {
122
36316
                    parser.exts |= extensions;
123
36316
                }
124
36
                ParsedAttribute::Ignored => {}
125
            }
126

            
127
36352
            parser.skip_ws().map_err(|e| parser.span_error(e))?;
128
        }
129

            
130
581524
        Ok(parser)
131
582376
    }
132

            
133
192229
    fn set_cursor(&mut self, cursor: ParserCursor) {
134
192229
        self.cursor = cursor;
135
192229
    }
136

            
137
110906
    pub fn span_error(&self, code: Error) -> SpannedError {
138
110906
        SpannedError {
139
110906
            code,
140
110906
            span: Span {
141
110906
                start: Position::from_src_end(&self.src[..self.prev_cursor.cursor]),
142
110906
                end: Position::from_src_end(&self.src[..self.cursor.cursor]),
143
110906
            },
144
110906
        }
145
110906
    }
146

            
147
7350
    pub fn is_number_start(&self, c: char) -> bool {
148
7350
        matches!(c, '0'..='9' | '+' | '-' | '.' | 'b') && (c != 'b' || self.src().starts_with("b'"))
149
7350
    }
150

            
151
97858725
    pub fn advance_bytes(&mut self, bytes: usize) {
152
97858725
        self.prev_cursor = self.cursor;
153
97858725
        self.cursor.cursor += bytes;
154
97858725
    }
155

            
156
46598391
    pub fn next_char(&mut self) -> Result<char> {
157
46598391
        let c = self.peek_char_or_eof()?;
158
46598082
        self.cursor.cursor += c.len_utf8();
159
46598082
        Ok(c)
160
46598391
    }
161

            
162
44884
    pub fn skip_next_char(&mut self) {
163
44884
        core::mem::drop(self.next_char());
164
44884
    }
165

            
166
76059148
    pub fn peek_char(&self) -> Option<char> {
167
76059148
        self.src().chars().next()
168
76059148
    }
169

            
170
57040970
    pub fn peek_char_or_eof(&self) -> Result<char> {
171
57040970
        self.peek_char().ok_or(Error::Eof)
172
57040970
    }
173

            
174
71036269
    pub fn check_char(&self, c: char) -> bool {
175
71036269
        self.src().starts_with(c)
176
71036269
    }
177

            
178
336475964
    pub fn check_str(&self, s: &str) -> bool {
179
336475964
        self.src().starts_with(s)
180
336475964
    }
181

            
182
866934194
    pub fn src(&self) -> &'a str {
183
866934194
        &self.src[self.cursor.cursor..]
184
866934194
    }
185

            
186
27382
    pub fn pre_ws_src(&self) -> &'a str {
187
27382
        &self.src[self.cursor.pre_ws_cursor..]
188
27382
    }
189

            
190
29831648
    pub fn consume_str(&mut self, s: &str) -> bool {
191
29831648
        if self.check_str(s) {
192
526723
            self.advance_bytes(s.len());
193

            
194
526723
            true
195
        } else {
196
29304925
            false
197
        }
198
29831648
    }
199

            
200
41778304
    pub fn consume_char(&mut self, c: char) -> bool {
201
41778304
        if self.check_char(c) {
202
10723176
            self.advance_bytes(c.len_utf8());
203

            
204
10723176
            true
205
        } else {
206
31055128
            false
207
        }
208
41778304
    }
209

            
210
73241
    fn consume_all(&mut self, all: &[&str]) -> Result<bool> {
211
73241
        all.iter()
212
183392
            .map(|elem| {
213
183392
                if self.consume_str(elem) {
214
183353
                    self.skip_ws()?;
215

            
216
183353
                    Ok(true)
217
                } else {
218
39
                    Ok(false)
219
                }
220
183392
            })
221
183392
            .try_fold(true, |acc, x| x.map(|x| x && acc))
222
73241
    }
223

            
224
154907
    pub fn expect_char(&mut self, expected: char, error: Error) -> Result<()> {
225
154907
        if self.consume_char(expected) {
226
134572
            Ok(())
227
        } else {
228
20335
            Err(error)
229
        }
230
154907
    }
231

            
232
    #[must_use]
233
40828511
    pub fn next_chars_while_len(&self, condition: fn(char) -> bool) -> usize {
234
40828511
        self.next_chars_while_from_len(0, condition)
235
40828511
    }
236

            
237
    #[must_use]
238
60150500
    pub fn next_chars_while_from_len(&self, from: usize, condition: fn(char) -> bool) -> usize {
239
60150500
        self.src()[from..]
240
269606915
            .find(|c| !condition(c))
241
60150500
            .unwrap_or(self.src().len() - from)
242
60150500
    }
243
}
244

            
245
/// actual parsing of ron tokens
246
impl<'a> Parser<'a> {
247
239003
    fn parse_integer_digits<T: Num>(
248
239003
        &mut self,
249
239003
        s: &str,
250
239003
        base: u8,
251
239003
        f: fn(&mut T, u8) -> bool,
252
239003
    ) -> Result<T> {
253
239003
        let mut num_acc = T::from_u8(0);
254

            
255
589164
        for (i, c) in s.char_indices() {
256
589164
            if c == '_' {
257
9846
                continue;
258
579318
            }
259

            
260
579318
            if num_acc.checked_mul_ext(base) {
261
890
                self.advance_bytes(s.len());
262
890
                return Err(Error::IntegerOutOfBounds);
263
578428
            }
264

            
265
578428
            let digit = Self::decode_hex(c)?;
266

            
267
578428
            if digit >= base {
268
2058
                self.advance_bytes(i);
269
2058
                return Err(Error::InvalidIntegerDigit { digit: c, base });
270
576370
            }
271

            
272
576370
            if f(&mut num_acc, digit) {
273
3381
                self.advance_bytes(s.len());
274
3381
                return Err(Error::IntegerOutOfBounds);
275
572989
            }
276
        }
277

            
278
232674
        self.advance_bytes(s.len());
279

            
280
232674
        Ok(num_acc)
281
239003
    }
282

            
283
246675
    fn parse_integer<T: Num>(&mut self, sign: i8, base: u8) -> Result<T> {
284
246675
        let num_bytes = self.next_chars_while_len(is_int_char);
285

            
286
246675
        if num_bytes == 0 {
287
4732
            return Err(Error::ExpectedInteger);
288
241943
        }
289

            
290
241943
        if self.check_char('_') {
291
2940
            return Err(Error::UnderscoreAtBeginning);
292
239003
        }
293

            
294
239003
        let s = &self.src()[..num_bytes];
295

            
296
239003
        if sign > 0 {
297
221223
            self.parse_integer_digits(s, base, T::checked_add_ext)
298
        } else {
299
17780
            self.parse_integer_digits(s, base, T::checked_sub_ext)
300
        }
301
246675
    }
302

            
303
    #[allow(clippy::too_many_lines)]
304
342067
    pub fn integer<T: Integer>(&mut self) -> Result<T> {
305
342067
        let src_backup = self.src();
306

            
307
342067
        let is_negative = match self.peek_char_or_eof()? {
308
            '+' => {
309
28
                self.skip_next_char();
310
28
                false
311
            }
312
            '-' => {
313
5267
                self.skip_next_char();
314
5267
                true
315
            }
316
228736
            'b' if self.consume_str("b'") => {
317
                // Parse a byte literal
318
228736
                let byte = match self.next_char()? {
319
200214
                    '\\' => match self.parse_escape(EscapeEncoding::Binary, true)? {
320
                        // we know that this byte is an ASCII character
321
199920
                        EscapeCharacter::Ascii(b) => b,
322
                        EscapeCharacter::Utf8(_) => {
323
294
                            return Err(Error::InvalidEscape(
324
294
                                "Unexpected Unicode escape in byte literal",
325
294
                            ))
326
                        }
327
                    },
328
28522
                    b if b.is_ascii() => b as u8,
329
294
                    _ => return Err(Error::ExpectedByteLiteral),
330
                };
331

            
332
228148
                if !self.consume_char('\'') {
333
294
                    return Err(Error::ExpectedByteLiteral);
334
227854
                }
335

            
336
227854
                let bytes_ron = &src_backup[..src_backup.len() - self.src().len()];
337

            
338
227854
                return T::try_from_parsed_integer(ParsedInteger::U8(byte), bytes_ron);
339
            }
340
108036
            _ => false,
341
        };
342
113331
        let sign = if is_negative { -1 } else { 1 };
343

            
344
113331
        let base = match () {
345
113331
            () if self.consume_str("0b") => 2,
346
110649
            () if self.consume_str("0o") => 8,
347
108849
            () if self.consume_str("0x") => 16,
348
107045
            () => 10,
349
        };
350

            
351
113331
        let num_bytes = self.next_chars_while_len(is_int_char);
352

            
353
113331
        if self.src()[num_bytes..].starts_with(['i', 'u']) {
354
12675
            let int_cursor = self.cursor;
355
12675
            self.advance_bytes(num_bytes);
356

            
357
            #[allow(clippy::never_loop)]
358
            loop {
359
12675
                let (res, suffix_bytes) = if self.consume_ident("i8") {
360
922
                    let suffix_bytes = self.src();
361
922
                    self.set_cursor(int_cursor);
362
922
                    (
363
922
                        self.parse_integer::<i8>(sign, base).map(ParsedInteger::I8),
364
922
                        suffix_bytes,
365
922
                    )
366
11753
                } else if self.consume_ident("i16") {
367
922
                    let suffix_bytes = self.src();
368
922
                    self.set_cursor(int_cursor);
369
922
                    (
370
922
                        self.parse_integer::<i16>(sign, base)
371
922
                            .map(ParsedInteger::I16),
372
922
                        suffix_bytes,
373
922
                    )
374
10831
                } else if self.consume_ident("i32") {
375
1260
                    let suffix_bytes = self.src();
376
1260
                    self.set_cursor(int_cursor);
377
1260
                    (
378
1260
                        self.parse_integer::<i32>(sign, base)
379
1260
                            .map(ParsedInteger::I32),
380
1260
                        suffix_bytes,
381
1260
                    )
382
9571
                } else if self.consume_ident("i64") {
383
922
                    let suffix_bytes = self.src();
384
922
                    self.set_cursor(int_cursor);
385
922
                    (
386
922
                        self.parse_integer::<i64>(sign, base)
387
922
                            .map(ParsedInteger::I64),
388
922
                        suffix_bytes,
389
922
                    )
390
8649
                } else if self.consume_ident("u8") {
391
2388
                    let suffix_bytes = self.src();
392
2388
                    self.set_cursor(int_cursor);
393
2388
                    (
394
2388
                        self.parse_integer::<u8>(sign, base).map(ParsedInteger::U8),
395
2388
                        suffix_bytes,
396
2388
                    )
397
6261
                } else if self.consume_ident("u16") {
398
1220
                    let suffix_bytes = self.src();
399
1220
                    self.set_cursor(int_cursor);
400
1220
                    (
401
1220
                        self.parse_integer::<u16>(sign, base)
402
1220
                            .map(ParsedInteger::U16),
403
1220
                        suffix_bytes,
404
1220
                    )
405
5041
                } else if self.consume_ident("u32") {
406
1252
                    let suffix_bytes = self.src();
407
1252
                    self.set_cursor(int_cursor);
408
1252
                    (
409
1252
                        self.parse_integer::<u32>(sign, base)
410
1252
                            .map(ParsedInteger::U32),
411
1252
                        suffix_bytes,
412
1252
                    )
413
3789
                } else if self.consume_ident("u64") {
414
1220
                    let suffix_bytes = self.src();
415
1220
                    self.set_cursor(int_cursor);
416
1220
                    (
417
1220
                        self.parse_integer::<u64>(sign, base)
418
1220
                            .map(ParsedInteger::U64),
419
1220
                        suffix_bytes,
420
1220
                    )
421
                } else {
422
                    #[cfg(feature = "integer128")]
423
1673
                    if self.consume_ident("i128") {
424
463
                        let suffix_bytes = self.src();
425
463
                        self.set_cursor(int_cursor);
426
463
                        (
427
463
                            self.parse_integer::<i128>(sign, base)
428
463
                                .map(ParsedInteger::I128),
429
463
                            suffix_bytes,
430
463
                        )
431
1210
                    } else if self.consume_ident("u128") {
432
612
                        let suffix_bytes = self.src();
433
612
                        self.set_cursor(int_cursor);
434
612
                        (
435
612
                            self.parse_integer::<u128>(sign, base)
436
612
                                .map(ParsedInteger::U128),
437
612
                            suffix_bytes,
438
612
                        )
439
                    } else {
440
598
                        break;
441
                    }
442
                    #[cfg(not(feature = "integer128"))]
443
                    {
444
896
                        break;
445
                    }
446
                };
447

            
448
10879
                if !matches!(
449
1937
                    &res,
450
                    Err(Error::UnderscoreAtBeginning | Error::InvalidIntegerDigit { .. })
451
10879
                ) {
452
10879
                    // Advance past the number suffix
453
10879
                    self.skip_identifier();
454
10879
                }
455

            
456
11181
                let integer_ron = &src_backup[..src_backup.len() - suffix_bytes.len()];
457

            
458
11181
                return res.and_then(|parsed| T::try_from_parsed_integer(parsed, integer_ron));
459
            }
460

            
461
1494
            self.set_cursor(int_cursor);
462
100656
        }
463

            
464
102150
        T::parse(self, sign, base)
465
342067
    }
466

            
467
9445709
    pub fn any_number(&mut self) -> Result<Number> {
468
9445709
        if self.consume_ident("inf") || self.consume_ident("inff32") {
469
298
            return Ok(Number::F32(crate::value::F32(core::f32::INFINITY)));
470
9445411
        } else if self.consume_ident("inff64") {
471
294
            return Ok(Number::F64(crate::value::F64(core::f64::INFINITY)));
472
9445117
        } else if self.consume_ident("NaN") || self.consume_ident("NaNf32") {
473
298
            return Ok(Number::F32(crate::value::F32(core::f32::NAN)));
474
9444819
        } else if self.consume_ident("NaNf64") {
475
294
            return Ok(Number::F64(crate::value::F64(core::f64::NAN)));
476
9444525
        }
477

            
478
9444525
        if self.next_bytes_is_float() {
479
9125538
            return match self.float::<ParsedFloat>()? {
480
3576
                ParsedFloat::F32(v) => Ok(Number::F32(v.into())),
481
9121962
                ParsedFloat::F64(v) => Ok(Number::F64(v.into())),
482
            };
483
318987
        }
484

            
485
318987
        let backup_cursor = self.cursor;
486

            
487
318987
        let (integer_err, integer_cursor) = match self.integer::<ParsedInteger>() {
488
315423
            Ok(integer) => {
489
315423
                return match integer {
490
894
                    ParsedInteger::I8(v) => Ok(Number::I8(v)),
491
592
                    ParsedInteger::I16(v) => Ok(Number::I16(v)),
492
592
                    ParsedInteger::I32(v) => Ok(Number::I32(v)),
493
592
                    ParsedInteger::I64(v) => Ok(Number::I64(v)),
494
                    #[cfg(feature = "integer128")]
495
590
                    ParsedInteger::I128(v) => Ok(Number::I128(v)),
496
309205
                    ParsedInteger::U8(v) => Ok(Number::U8(v)),
497
890
                    ParsedInteger::U16(v) => Ok(Number::U16(v)),
498
592
                    ParsedInteger::U32(v) => Ok(Number::U32(v)),
499
592
                    ParsedInteger::U64(v) => Ok(Number::U64(v)),
500
                    #[cfg(feature = "integer128")]
501
884
                    ParsedInteger::U128(v) => Ok(Number::U128(v)),
502
                }
503
            }
504
3564
            Err(err) => (err, self.cursor),
505
        };
506

            
507
3564
        self.set_cursor(backup_cursor);
508

            
509
        // Fall-back to parse an out-of-range integer as a float
510
3564
        match self.float::<ParsedFloat>() {
511
2968
            Ok(ParsedFloat::F32(v)) if self.cursor >= integer_cursor => Ok(Number::F32(v.into())),
512
596
            Ok(ParsedFloat::F64(v)) if self.cursor >= integer_cursor => Ok(Number::F64(v.into())),
513
            _ => {
514
                // Return the more precise integer error
515
1323
                self.set_cursor(integer_cursor);
516
1323
                Err(integer_err)
517
            }
518
        }
519
9445709
    }
520

            
521
32784
    pub fn bool(&mut self) -> Result<bool> {
522
32784
        if self.consume_ident("true") {
523
18298
            Ok(true)
524
14486
        } else if self.consume_ident("false") {
525
14450
            Ok(false)
526
        } else {
527
36
            Err(Error::ExpectedBoolean)
528
        }
529
32784
    }
530

            
531
71711
    pub fn char(&mut self) -> Result<char> {
532
71711
        self.expect_char('\'', Error::ExpectedChar)?;
533

            
534
51968
        let c = self.next_char()?;
535

            
536
51968
        let c = if c == '\\' {
537
3834
            match self.parse_escape(EscapeEncoding::Utf8, true)? {
538
                // we know that this byte is an ASCII character
539
1776
                EscapeCharacter::Ascii(b) => char::from(b),
540
1176
                EscapeCharacter::Utf8(c) => c,
541
            }
542
        } else {
543
48134
            c
544
        };
545

            
546
51086
        self.expect_char('\'', Error::ExpectedChar)?;
547

            
548
51086
        Ok(c)
549
71711
    }
550

            
551
9555457
    pub fn comma(&mut self) -> Result<bool> {
552
9555457
        self.skip_ws()?;
553

            
554
9555457
        if self.consume_char(',') {
555
9368671
            self.skip_ws()?;
556

            
557
9368671
            Ok(true)
558
        } else {
559
186786
            Ok(false)
560
        }
561
9555457
    }
562

            
563
    /// Only returns true if the char after `ident` cannot belong
564
    /// to an identifier.
565
208604560
    pub fn check_ident(&mut self, ident: &str) -> bool {
566
208604560
        self.check_str(ident) && !self.check_ident_other_char(ident.len())
567
208604560
    }
568

            
569
312445
    fn check_ident_other_char(&self, index: usize) -> bool {
570
312445
        self.src()[index..]
571
312445
            .chars()
572
312445
            .next()
573
312445
            .map_or(false, is_xid_continue)
574
312445
    }
575

            
576
    /// Check which type of struct we are currently parsing. The parsing state
577
    ///  is only changed in case of an error, to provide a better position.
578
    ///
579
    /// [`NewtypeMode::NoParensMeanUnit`] detects (tuple) structs by a leading
580
    ///  opening bracket and reports a unit struct otherwise.
581
    /// [`NewtypeMode::InsideNewtype`] skips an initial check for unit structs,
582
    ///  and means that any leading opening bracket is not considered to open
583
    ///  a (tuple) struct but to be part of the structs inner contents.
584
    ///
585
    /// [`TupleMode::ImpreciseTupleOrNewtype`] only performs a cheap, O(1),
586
    ///  single-identifier lookahead check to distinguish tuple structs from
587
    ///  non-tuple structs.
588
    /// [`TupleMode::DifferentiateNewtype`] performs an expensive, O(N), look-
589
    ///  ahead over the entire next value tree, which can span the entirety of
590
    ///  the remaining document in the worst case.
591
82546
    pub fn check_struct_type(
592
82546
        &mut self,
593
82546
        newtype: NewtypeMode,
594
82546
        tuple: TupleMode,
595
82546
    ) -> Result<StructType> {
596
82546
        fn check_struct_type_inner(
597
82546
            parser: &mut Parser,
598
82546
            newtype: NewtypeMode,
599
82546
            tuple: TupleMode,
600
82546
        ) -> Result<StructType> {
601
82546
            if matches!(newtype, NewtypeMode::NoParensMeanUnit) && !parser.consume_char('(') {
602
12940
                return Ok(StructType::Unit);
603
69606
            }
604

            
605
69606
            parser.skip_ws()?;
606

            
607
            // Check for `Ident()`, which could be
608
            // - a zero-field struct or tuple (variant)
609
            // - an unwrapped newtype around a unit
610
69602
            if matches!(newtype, NewtypeMode::NoParensMeanUnit) && parser.check_char(')') {
611
882
                return Ok(StructType::EmptyTuple);
612
68720
            }
613

            
614
68720
            if parser.skip_identifier().is_some() {
615
48984
                parser.skip_ws()?;
616

            
617
48984
                match parser.peek_char() {
618
                    // Definitely a struct with named fields
619
42802
                    Some(':') => return Ok(StructType::Named),
620
                    // Definitely a tuple-like struct with fields
621
                    Some(',') => {
622
4418
                        parser.skip_next_char();
623
4418
                        parser.skip_ws()?;
624
4418
                        if parser.check_char(')') {
625
                            // A one-element tuple could be a newtype
626
                            return Ok(StructType::NewtypeTuple);
627
4418
                        }
628
                        // Definitely a tuple struct with more than one field
629
4418
                        return Ok(StructType::NonNewtypeTuple);
630
                    }
631
                    // Either a newtype or a tuple struct
632
1176
                    Some(')') => return Ok(StructType::NewtypeTuple),
633
                    // Something else, let's investigate further
634
588
                    Some(_) | None => (),
635
                };
636
19736
            }
637

            
638
20324
            if matches!(tuple, TupleMode::ImpreciseTupleOrNewtype) {
639
13841
                return Ok(StructType::AnyTuple);
640
6483
            }
641

            
642
6483
            let mut braces = 1_usize;
643
6483
            let mut more_than_one = false;
644

            
645
            // Skip ahead to see if the value is followed by another value
646
25623
            while braces > 0 {
647
                // Skip spurious braces in comments, strings, and characters
648
19743
                parser.skip_ws()?;
649
19743
                let cursor_backup = parser.cursor;
650
19743
                if parser.char().is_err() {
651
19743
                    parser.set_cursor(cursor_backup);
652
19743
                }
653
19743
                let cursor_backup = parser.cursor;
654
19743
                match parser.string() {
655
1176
                    Ok(_) => (),
656
                    // prevent quadratic complexity backtracking for unterminated string
657
                    Err(err @ (Error::ExpectedStringEnd | Error::Eof)) => return Err(err),
658
18567
                    Err(_) => parser.set_cursor(cursor_backup),
659
                }
660
19743
                let cursor_backup = parser.cursor;
661
                // we have already checked for strings, which subsume base64 byte strings
662
19743
                match parser.byte_string_no_base64() {
663
882
                    Ok(_) => (),
664
                    // prevent quadratic complexity backtracking for unterminated byte string
665
                    Err(err @ (Error::ExpectedStringEnd | Error::Eof)) => return Err(err),
666
18861
                    Err(_) => parser.set_cursor(cursor_backup),
667
                }
668

            
669
19743
                let c = parser.next_char()?;
670
19728
                if matches!(c, '(' | '[' | '{') {
671
1485
                    braces += 1;
672
18243
                } else if matches!(c, ')' | ']' | '}') {
673
7365
                    braces -= 1;
674
10893
                } else if c == ',' && braces == 1 {
675
588
                    parser.skip_ws()?;
676
588
                    more_than_one = !parser.check_char(')');
677
588
                    break;
678
10290
                }
679
            }
680

            
681
6468
            if more_than_one {
682
294
                Ok(StructType::NonNewtypeTuple)
683
            } else {
684
6174
                Ok(StructType::NewtypeTuple)
685
            }
686
82546
        }
687

            
688
        // Create a temporary working copy
689
82546
        let backup_cursor = self.cursor;
690

            
691
82546
        let result = check_struct_type_inner(self, newtype, tuple);
692

            
693
82546
        if result.is_ok() {
694
82527
            // Revert the parser to before the struct type check
695
82527
            self.set_cursor(backup_cursor);
696
82527
        }
697

            
698
82546
        result
699
82546
    }
700

            
701
    /// Only returns true if the char after `ident` cannot belong
702
    /// to an identifier.
703
198850947
    pub fn consume_ident(&mut self, ident: &str) -> bool {
704
198850947
        if self.check_ident(ident) {
705
166976
            self.advance_bytes(ident.len());
706

            
707
166976
            true
708
        } else {
709
198683971
            false
710
        }
711
198850947
    }
712

            
713
88880
    pub fn consume_struct_name(&mut self, ident: &'static str) -> Result<bool> {
714
88880
        if self.check_ident("") {
715
70903
            if self.exts.contains(Extensions::EXPLICIT_STRUCT_NAMES) {
716
882
                return Err(Error::ExpectedStructName(ident.to_string()));
717
70021
            }
718

            
719
70021
            return Ok(false);
720
17977
        }
721

            
722
17977
        let found_ident = match self.identifier() {
723
15919
            Ok(maybe_ident) => maybe_ident,
724
1470
            Err(Error::SuggestRawIdentifier(found_ident)) if found_ident == ident => {
725
294
                return Err(Error::SuggestRawIdentifier(found_ident))
726
            }
727
1764
            Err(_) => return Err(Error::ExpectedNamedStructLike(ident)),
728
        };
729

            
730
15919
        if ident.is_empty() {
731
324
            return Err(Error::ExpectedNamedStructLike(ident));
732
15595
        }
733

            
734
15595
        if found_ident != ident {
735
1776
            return Err(Error::ExpectedDifferentStructName {
736
1776
                expected: ident,
737
1776
                found: String::from(found_ident),
738
1776
            });
739
13819
        }
740

            
741
13819
        Ok(true)
742
88880
    }
743

            
744
    /// Parse a document attribute at the current cursor position.
745
618434
    fn attribute(&mut self) -> Result<ParsedAttribute> {
746
618434
        if !self.check_char('#') {
747
581524
            return Ok(ParsedAttribute::None);
748
36910
        }
749

            
750
36910
        if !self.consume_all(&["#", "!", "["])? {
751
12
            return Err(Error::ExpectedAttribute);
752
36898
        }
753

            
754
36898
        self.skip_ws()?;
755
36898
        if self.consume_ident("enable") {
756
36862
            self.skip_ws()?;
757
36862
            if !self.consume_str("(") {
758
                return Err(Error::ExpectedAttribute);
759
36862
            }
760

            
761
36862
            self.skip_ws()?;
762
36862
            let extensions = self.extension_list()?;
763
36331
            self.skip_ws()?;
764

            
765
36331
            if self.consume_all(&[")", "]"])? {
766
36316
                Ok(ParsedAttribute::Extensions(extensions))
767
            } else {
768
15
                Err(Error::ExpectedAttributeEnd)
769
            }
770
36
        } else if self.consume_ident("type") || self.consume_ident("schema") {
771
36
            self.skip_ws()?;
772
36
            if !self.consume_str("=") {
773
                return Err(Error::ExpectedAttribute);
774
36
            }
775

            
776
36
            self.skip_ws()?;
777
36
            self.string()?;
778
36
            self.skip_ws()?;
779

            
780
36
            if self.consume_str("]") {
781
36
                Ok(ParsedAttribute::Ignored)
782
            } else {
783
                Err(Error::ExpectedAttributeEnd)
784
            }
785
        } else {
786
            Err(Error::ExpectedAttribute)
787
        }
788
618434
    }
789

            
790
    /// Returns the extensions bit mask.
791
36862
    fn extension_list(&mut self) -> Result<Extensions> {
792
36862
        let mut extensions = Extensions::empty();
793

            
794
        loop {
795
37156
            let ident = self.identifier()?;
796
37156
            let extension = Extensions::from_ident(ident)
797
37156
                .ok_or_else(|| Error::NoSuchExtension(ident.into()))?;
798

            
799
37141
            extensions |= extension;
800

            
801
37141
            let comma = self.comma()?;
802

            
803
            // If we have no comma but another item, return an error
804
37141
            if !comma && self.check_ident_other_char(0) {
805
516
                return Err(Error::ExpectedComma);
806
36625
            }
807

            
808
            // If there's no comma, assume the list ended.
809
            // If there is, it might be a trailing one, thus we only
810
            // continue the loop if we get an ident char.
811
36625
            if !comma || !self.check_ident_other_char(0) {
812
36331
                break;
813
294
            }
814
        }
815

            
816
36331
        Ok(extensions)
817
36862
    }
818

            
819
9130007
    pub fn float<T: Float>(&mut self) -> Result<T> {
820
        const F32_SUFFIX: &str = "f32";
821
        const F64_SUFFIX: &str = "f64";
822

            
823
54777946
        for (literal, value_f32, value_f64) in &[
824
9130007
            ("inf", f32::INFINITY, f64::INFINITY),
825
9130007
            ("+inf", f32::INFINITY, f64::INFINITY),
826
9130007
            ("-inf", f32::NEG_INFINITY, f64::NEG_INFINITY),
827
9130007
            ("NaN", f32::NAN, f64::NAN),
828
9130007
            ("+NaN", f32::NAN, f64::NAN),
829
9130007
            ("-NaN", -f32::NAN, -f64::NAN),
830
9130007
        ] {
831
54777946
            if self.consume_ident(literal) {
832
96
                return T::parse(literal);
833
54777850
            }
834

            
835
54777850
            if let Some(suffix) = self.src().strip_prefix(literal) {
836
1220
                if let Some(post_suffix) = suffix.strip_prefix(F32_SUFFIX) {
837
608
                    if !post_suffix.chars().next().map_or(false, is_xid_continue) {
838
604
                        let float_ron = &self.src()[..literal.len() + F32_SUFFIX.len()];
839
604
                        self.advance_bytes(literal.len() + F32_SUFFIX.len());
840
604
                        return T::try_from_parsed_float(ParsedFloat::F32(*value_f32), float_ron);
841
4
                    }
842
612
                }
843

            
844
616
                if let Some(post_suffix) = suffix.strip_prefix(F64_SUFFIX) {
845
608
                    if !post_suffix.chars().next().map_or(false, is_xid_continue) {
846
604
                        let float_ron = &self.src()[..literal.len() + F64_SUFFIX.len()];
847
604
                        self.advance_bytes(literal.len() + F64_SUFFIX.len());
848
604
                        return T::try_from_parsed_float(ParsedFloat::F64(*value_f64), float_ron);
849
4
                    }
850
8
                }
851
54776630
            }
852
        }
853

            
854
9128703
        let raw_bytes = self.next_chars_while_len(is_float_char);
855
9128703
        let src = &self.src()[..raw_bytes];
856
9128703
        let num_bytes = src.find("..").unwrap_or(raw_bytes);
857

            
858
9128703
        if num_bytes == 0 {
859
46
            return Err(Error::ExpectedFloat);
860
9128657
        }
861

            
862
9128657
        if self.check_char('_') {
863
4
            return Err(Error::UnderscoreAtBeginning);
864
9128653
        }
865

            
866
9128653
        let mut f = String::with_capacity(num_bytes);
867
9128653
        let mut allow_underscore = false;
868

            
869
82291429
        for (i, c) in self.src()[..num_bytes].char_indices() {
870
800
            match c {
871
792
                '_' if allow_underscore => continue,
872
                '_' => {
873
8
                    self.advance_bytes(i);
874
8
                    return Err(Error::FloatUnderscore);
875
                }
876
73162279
                '0'..='9' | 'e' | 'E' => allow_underscore = true,
877
9126021
                '.' => allow_underscore = false,
878
2329
                _ => (),
879
            }
880

            
881
            // we know that the byte is an ASCII character here
882
82290629
            f.push(c);
883
        }
884

            
885
9128645
        if self.src()[num_bytes..].starts_with('f') {
886
2094
            let backup_cursor = self.cursor;
887
2094
            self.advance_bytes(num_bytes);
888

            
889
            #[allow(clippy::never_loop)]
890
            loop {
891
2094
                let res = if self.consume_ident(F32_SUFFIX) {
892
1192
                    f32::from_str(&f).map(ParsedFloat::F32)
893
902
                } else if self.consume_ident(F64_SUFFIX) {
894
604
                    f64::from_str(&f).map(ParsedFloat::F64)
895
                } else {
896
298
                    break;
897
                };
898

            
899
1796
                let parsed = if let Ok(parsed) = res {
900
1788
                    parsed
901
                } else {
902
8
                    self.set_cursor(backup_cursor);
903
8
                    return Err(Error::ExpectedFloat);
904
                };
905

            
906
1788
                let float_ron = &self.src[backup_cursor.cursor..self.cursor.cursor];
907

            
908
1788
                return T::try_from_parsed_float(parsed, float_ron);
909
            }
910

            
911
298
            self.set_cursor(backup_cursor);
912
9126551
        }
913

            
914
9126849
        let value = T::parse(&f)?;
915

            
916
9126829
        self.advance_bytes(num_bytes);
917

            
918
9126829
        Ok(value)
919
9130007
    }
920

            
921
9741629
    pub fn skip_identifier(&mut self) -> Option<&'a str> {
922
        #[allow(clippy::nonminimal_bool)]
923
9741629
        if self.check_str("b\"") // byte string
924
9740151
            || self.check_str("b'") // byte literal
925
9513477
            || self.check_str("br#") // raw byte string
926
9512595
            || self.check_str("br\"") // raw byte string
927
9511713
            || self.check_str("r\"") // raw string
928
9511125
            || self.check_str("r#\"") // raw string
929
9510831
            || self.check_str("r##") // raw string
930
9510537
            || false
931
        {
932
231092
            return None;
933
9510537
        }
934

            
935
9510537
        if self.check_str("r#") {
936
            // maybe a raw identifier
937
12
            let len = self.next_chars_while_from_len(2, is_ident_raw_char);
938
12
            if len > 0 {
939
4
                let ident = &self.src()[2..2 + len];
940
4
                self.advance_bytes(2 + len);
941
4
                return Some(ident);
942
8
            }
943
8
            return None;
944
9510525
        }
945

            
946
9510525
        if let Some(c) = self.peek_char() {
947
            // maybe a normal identifier
948
9509055
            if is_ident_first_char(c) {
949
117215
                let len =
950
117215
                    c.len_utf8() + self.next_chars_while_from_len(c.len_utf8(), is_xid_continue);
951
117215
                let ident = &self.src()[..len];
952
117215
                self.advance_bytes(len);
953
117215
                return Some(ident);
954
9391840
            }
955
1470
        }
956

            
957
9393310
        None
958
9741629
    }
959

            
960
328394
    pub fn identifier(&mut self) -> Result<&'a str> {
961
328394
        let first = self.peek_char_or_eof()?;
962
328394
        if !is_ident_first_char(first) {
963
2364
            if is_ident_raw_char(first) {
964
1176
                let ident_bytes = self.next_chars_while_len(is_ident_raw_char);
965
1176
                return Err(Error::SuggestRawIdentifier(
966
1176
                    self.src()[..ident_bytes].into(),
967
1176
                ));
968
1188
            }
969

            
970
1188
            return Err(Error::ExpectedIdentifier);
971
326030
        }
972

            
973
        // If the next 2-3 bytes signify the start of a (raw) (byte) string
974
        //  literal, return an error.
975
        #[allow(clippy::nonminimal_bool)]
976
326030
        if self.check_str("b\"") // byte string
977
325736
            || self.check_str("b'") // byte literal
978
325442
            || self.check_str("br#") // raw byte string
979
325148
            || self.check_str("br\"") // raw byte string
980
324854
            || self.check_str("r\"") // raw string
981
324560
            || self.check_str("r#\"") // raw string
982
324266
            || self.check_str("r##") // raw string
983
323972
            || false
984
        {
985
2058
            return Err(Error::ExpectedIdentifier);
986
323972
        }
987

            
988
323972
        let length = if self.check_str("r#") {
989
7672
            let cursor_backup = self.cursor;
990

            
991
7672
            self.advance_bytes(2);
992

            
993
            // Note: it's important to check this before advancing forward, so that
994
            // the value-type deserializer can fall back to parsing it differently.
995
7672
            if !matches!(self.peek_char(), Some(c) if is_ident_raw_char(c)) {
996
588
                self.set_cursor(cursor_backup);
997
588
                return Err(Error::ExpectedIdentifier);
998
7084
            }
999

            
7084
            self.next_chars_while_len(is_ident_raw_char)
316300
        } else if first == 'r' {
588
            let std_ident_length = self.next_chars_while_len(is_xid_continue);
588
            let raw_ident_length = self.next_chars_while_len(is_ident_raw_char);
588
            if raw_ident_length > std_ident_length {
294
                return Err(Error::SuggestRawIdentifier(
294
                    self.src()[..raw_ident_length].into(),
294
                ));
294
            }
294
            std_ident_length
        } else {
315712
            let std_ident_length = first.len_utf8()
315712
                + self.next_chars_while_from_len(first.len_utf8(), is_xid_continue);
315712
            let raw_ident_length = self.next_chars_while_len(is_ident_raw_char);
315712
            if raw_ident_length > std_ident_length {
882
                return Err(Error::SuggestRawIdentifier(
882
                    self.src()[..raw_ident_length].into(),
882
                ));
314830
            }
314830
            std_ident_length
        };
322208
        let ident = &self.src()[..length];
322208
        self.advance_bytes(length);
322208
        Ok(ident)
328394
    }
9444529
    pub fn next_bytes_is_float(&mut self) -> bool {
9444529
        if let Some(c) = self.peek_char() {
9444525
            let skip = match c {
5374
                '+' | '-' => 1,
9439151
                _ => 0,
            };
9444525
            let raw_float_len = self.next_chars_while_from_len(skip, is_float_char);
            // Trim at ".." to avoid treating range operators as float chars.
            //
            // Only search within the float-char run: the result is clamped to
            // `raw_float_len` anyway, so a match at or beyond it cannot change the
            // outcome. Searching the whole remaining input made this O(remaining)
            // per number, i.e. quadratic in the number count for documents that
            // contain no ".." at all (every number then scanned to EOF).
            //
            // A ".." cannot straddle the end of the run: that would require
            // `src[raw_float_len] == '.'`, but '.' is a float char and would have
            // been part of the run. `any_number` above already uses this same
            // bounded-slice form.
9444525
            let valid_float_len = self.src()[skip..][..raw_float_len]
9444525
                .find("..")
9444525
                .map_or(raw_float_len, |i| i.min(raw_float_len));
9444525
            let valid_int_len = self.next_chars_while_from_len(skip, is_int_char);
9444525
            valid_float_len > valid_int_len
        } else {
4
            false
        }
9444529
    }
31238520
    pub fn skip_ws(&mut self) -> Result<()> {
31238520
        if (self.cursor.last_ws_len != WS_CURSOR_UNCLOSED_LINE)
31237928
            && ((self.cursor.pre_ws_cursor + self.cursor.last_ws_len) < self.cursor.cursor)
20737763
        {
20737763
            // the last whitespace is disjoint from this one, we need to track a new one
20737763
            self.cursor.pre_ws_cursor = self.cursor.cursor;
20737763
        }
31238520
        if self.src().is_empty() {
469400
            return Ok(());
30769120
        }
        loop {
30798822
            self.advance_bytes(self.next_chars_while_len(is_whitespace_char));
30798822
            match self.skip_comment()? {
30767054
                None => break,
                Some(Comment::UnclosedLine) => {
1180
                    self.cursor.last_ws_len = WS_CURSOR_UNCLOSED_LINE;
1180
                    return Ok(());
                }
29702
                Some(Comment::ClosedLine | Comment::Block) => continue,
            }
        }
30767054
        self.cursor.last_ws_len = self.cursor.cursor - self.cursor.pre_ws_cursor;
30767054
        Ok(())
31238520
    }
18816
    pub fn has_unclosed_line_comment(&self) -> bool {
18816
        self.src().is_empty() && self.cursor.last_ws_len == WS_CURSOR_UNCLOSED_LINE
18816
    }
9162
    pub fn byte_string(&mut self) -> Result<ParsedByteStr<'a>> {
16
        fn expected_byte_string_found_base64(
16
            base64_str: &ParsedStr,
16
            byte_str: &ParsedByteStr,
16
        ) -> Error {
16
            let byte_str = match &byte_str {
16
                ParsedByteStr::Allocated(b) => b.as_slice(),
                ParsedByteStr::Slice(b) => b,
            }
16
            .iter()
120
            .flat_map(|c| core::ascii::escape_default(*c))
16
            .map(char::from)
16
            .collect::<String>();
16
            let base64_str = match &base64_str {
                ParsedStr::Allocated(s) => s.as_str(),
16
                ParsedStr::Slice(s) => s,
            };
16
            Error::InvalidValueForType {
16
                expected: format!("the Rusty byte string b\"{}\"", byte_str),
16
                found: format!("the ambiguous base64 string {:?}", base64_str),
16
            }
16
        }
        // FIXME @juntyr: remove in v0.13, since only byte_string_no_base64 will
        //                be used
9162
        if self.consume_char('"') {
8
            let base64_str = self.escaped_string()?;
8
            let base64_result = ParsedByteStr::try_from_base64(&base64_str);
8
            match base64_result {
8
                Some(byte_str) => Err(expected_byte_string_found_base64(&base64_str, &byte_str)),
                None => Err(Error::ExpectedByteString),
            }
9154
        } else if self.consume_char('r') {
12
            let base64_str = self.raw_string()?;
12
            let base64_result = ParsedByteStr::try_from_base64(&base64_str);
12
            match base64_result {
8
                Some(byte_str) => Err(expected_byte_string_found_base64(&base64_str, &byte_str)),
4
                None => Err(Error::ExpectedByteString),
            }
        } else {
9142
            self.byte_string_no_base64()
        }
9162
    }
28885
    pub fn byte_string_no_base64(&mut self) -> Result<ParsedByteStr<'a>> {
28885
        if self.consume_str("b\"") {
6202
            self.escaped_byte_string()
22683
        } else if self.consume_str("br") {
3822
            self.raw_byte_string()
        } else {
18861
            Err(Error::ExpectedByteString)
        }
28885
    }
6202
    fn escaped_byte_string(&mut self) -> Result<ParsedByteStr<'a>> {
6202
        match self.escaped_byte_buf(EscapeEncoding::Binary) {
5614
            Ok((bytes, advance)) => {
5614
                self.advance_bytes(advance);
5614
                Ok(bytes)
            }
588
            Err(err) => Err(err),
        }
6202
    }
3822
    fn raw_byte_string(&mut self) -> Result<ParsedByteStr<'a>> {
3822
        match self.raw_byte_buf() {
3234
            Ok((bytes, advance)) => {
3234
                self.advance_bytes(advance);
3234
                Ok(bytes)
            }
294
            Err(Error::ExpectedString) => Err(Error::ExpectedByteString),
294
            Err(err) => Err(err),
        }
3822
    }
115109
    pub fn string(&mut self) -> Result<ParsedStr<'a>> {
115109
        if self.consume_char('"') {
91480
            self.escaped_string()
23629
        } else if self.consume_char('r') {
3286
            self.raw_string()
        } else {
20343
            Err(Error::ExpectedString)
        }
115109
    }
91488
    fn escaped_string(&mut self) -> Result<ParsedStr<'a>> {
91488
        match self.escaped_byte_buf(EscapeEncoding::Utf8) {
89415
            Ok((bytes, advance)) => {
89415
                let string = ParsedStr::try_from_bytes(bytes).map_err(Error::from)?;
89415
                self.advance_bytes(advance);
89415
                Ok(string)
            }
2073
            Err(err) => Err(err),
        }
91488
    }
3298
    fn raw_string(&mut self) -> Result<ParsedStr<'a>> {
3298
        match self.raw_byte_buf() {
2706
            Ok((bytes, advance)) => {
2706
                let string = ParsedStr::try_from_bytes(bytes).map_err(Error::from)?;
2706
                self.advance_bytes(advance);
2706
                Ok(string)
            }
592
            Err(err) => Err(err),
        }
3298
    }
97690
    fn escaped_byte_buf(&mut self, encoding: EscapeEncoding) -> Result<(ParsedByteStr<'a>, usize)> {
        // Checking for '"' and '\\' separately is faster than searching for both at the same time
97690
        let str_end = self.src().find('"').ok_or(Error::ExpectedStringEnd)?;
97087
        let escape = self.src()[..str_end].find('\\');
97087
        if let Some(escape) = escape {
            // Now check if escaping is used inside the string
13858
            let mut i = escape;
13858
            let mut s = self.src().as_bytes()[..i].to_vec();
            loop {
45597168
                self.advance_bytes(i + 1);
45597168
                match self.parse_escape(encoding, false)? {
45583048
                    EscapeCharacter::Ascii(c) => s.push(c),
12062
                    EscapeCharacter::Utf8(c) => match c.len_utf8() {
11466
                        1 => s.push(c as u8),
596
                        len => {
596
                            let start = s.len();
596
                            s.extend(core::iter::repeat(0).take(len));
596
                            c.encode_utf8(&mut s[start..]);
596
                        }
                    },
                }
                // Unlike the non-escaped case above, searching for '"' and '\\'
                // separately is *not* sound here: `find('"')` scans all the way to
                // the closing quote, but the cursor only advances by one escape per
                // iteration, so a string with N escapes rescans the tail N times.
                // Only the first of '"' / '\\' is needed, and scanning just to the
                // nearest delimiter keeps the loop linear.
45595110
                let next = self
45595110
                    .src()
45595110
                    .find(['"', '\\'])
45595110
                    .ok_or(Error::ExpectedStringEnd)?;
45595110
                s.extend_from_slice(&self.src().as_bytes()[..next]);
                // `next` indexes an ASCII byte, so byte indexing is valid here.
45595110
                if self.src().as_bytes()[next] == b'\\' {
45583310
                    i = next;
45583310
                } else {
                    // Advance to the end of the string + 1 for the `"`.
11800
                    break Ok((ParsedByteStr::Allocated(s), next + 1));
                }
            }
        } else {
83229
            let s = &self.src().as_bytes()[..str_end];
            // Advance by the number of bytes of the string + 1 for the `"`.
83229
            Ok((ParsedByteStr::Slice(s), str_end + 1))
        }
97690
    }
7120
    fn raw_byte_buf(&mut self) -> Result<(ParsedByteStr<'a>, usize)> {
14228
        let num_hashes = self.next_chars_while_len(|c| c == '#');
7120
        let hashes = &self.src()[..num_hashes];
7120
        self.advance_bytes(num_hashes);
7120
        self.expect_char('"', Error::ExpectedString)?;
6528
        let ending = ["\"", hashes].concat();
6528
        let i = self.src().find(&ending).ok_or(Error::ExpectedStringEnd)?;
5940
        let s = &self.src().as_bytes()[..i];
        // Advance by the number of bytes of the byte string
        // + `num_hashes` + 1 for the `"`.
5940
        Ok((ParsedByteStr::Slice(s), i + num_hashes + 1))
7120
    }
207982
    fn decode_ascii_escape(&mut self) -> Result<u8> {
207982
        let mut n = 0;
207982
        for _ in 0..2 {
415964
            n <<= 4;
415964
            let byte = self.next_char()?;
415964
            let decoded = Self::decode_hex(byte)?;
415376
            n |= decoded;
        }
207394
        Ok(n)
207982
    }
    #[inline]
1015560
    fn decode_hex(c: char) -> Result<u8> {
1015560
        if !c.is_ascii() {
294
            return Err(Error::InvalidEscape("Non-hex digit found"));
1015266
        }
        // c is an ASCII character that can be losslessly cast to u8
1015266
        match c as u8 {
1014972
            c @ b'0'..=b'9' => Ok(c - b'0'),
116488
            c @ b'a'..=b'f' => Ok(10 + c - b'a'),
59976
            c @ b'A'..=b'F' => Ok(10 + c - b'A'),
294
            _ => Err(Error::InvalidEscape("Non-hex digit found")),
        }
1015560
    }
45801216
    fn parse_escape(&mut self, encoding: EscapeEncoding, is_char: bool) -> Result<EscapeCharacter> {
45801216
        let c = match self.next_char()? {
894
            '\'' => EscapeCharacter::Ascii(b'\''),
3846
            '"' => EscapeCharacter::Ascii(b'"'),
2940
            '\\' => EscapeCharacter::Ascii(b'\\'),
45572940
            'n' => EscapeCharacter::Ascii(b'\n'),
588
            'r' => EscapeCharacter::Ascii(b'\r'),
588
            't' => EscapeCharacter::Ascii(b'\t'),
1764
            '0' => EscapeCharacter::Ascii(b'\0'),
            'x' => {
                // Fast exit for ascii escape in byte string
204720
                let b: u8 = self.decode_ascii_escape()?;
204132
                if let EscapeEncoding::Binary = encoding {
201184
                    return Ok(EscapeCharacter::Ascii(b));
2948
                }
                // Fast exit for ascii character in UTF-8 string
2948
                let mut bytes = [b, 0, 0, 0];
2948
                if let Ok(Some(c)) = from_utf8(&bytes[..=0]).map(|s| s.chars().next()) {
882
                    return Ok(EscapeCharacter::Utf8(c));
2066
                }
2066
                if is_char {
                    // Character literals are not allowed to use multiple byte
                    //  escapes to build a unicode character
294
                    return Err(Error::InvalidEscape(
294
                        "Not a valid byte-escaped Unicode character",
294
                    ));
1772
                }
                // UTF-8 character needs up to four bytes and we have already
                //  consumed one, so at most three to go
4434
                for i in 1..4 {
4434
                    if !self.consume_str(r"\x") {
1176
                        return Err(Error::InvalidEscape(
1176
                            "Not a valid byte-escaped Unicode character",
1176
                        ));
3258
                    }
3258
                    bytes[i] = self.decode_ascii_escape()?;
                    // Check if we now have a valid UTF-8 character
3258
                    if let Ok(Some(c)) = from_utf8(&bytes[..=i]).map(|s| s.chars().next()) {
302
                        return Ok(EscapeCharacter::Utf8(c));
2956
                    }
                }
294
                return Err(Error::InvalidEscape(
294
                    "Not a valid byte-escaped Unicode character",
294
                ));
            }
            'u' => {
12642
                self.expect_char('{', Error::InvalidEscape("Missing { in Unicode escape"))?;
12642
                let mut bytes: u32 = 0;
12642
                let mut num_digits = 0;
33810
                while num_digits < 6 {
33810
                    let byte = self.peek_char_or_eof()?;
33810
                    if byte == '}' {
12642
                        break;
21168
                    }
21168
                    self.skip_next_char();
21168
                    num_digits += 1;
21168
                    let byte = Self::decode_hex(byte)?;
21168
                    bytes <<= 4;
21168
                    bytes |= u32::from(byte);
                }
12642
                if num_digits == 0 {
294
                    return Err(Error::InvalidEscape(
294
                        "Expected 1-6 digits, got 0 digits in Unicode escape",
294
                    ));
12348
                }
12348
                self.expect_char(
                    '}',
12348
                    Error::InvalidEscape("No } at the end of Unicode escape"),
                )?;
12348
                let c = char_from_u32(bytes).ok_or(Error::InvalidEscape(
12348
                    "Not a valid Unicode-escaped character",
12348
                ))?;
12348
                EscapeCharacter::Utf8(c)
            }
294
            _ => return Err(Error::InvalidEscape("Unknown escape character")),
        };
45595908
        Ok(c)
45801216
    }
30798822
    fn skip_comment(&mut self) -> Result<Option<Comment>> {
30798822
        if self.consume_char('/') {
31768
            match self.next_char()? {
                '/' => {
130968
                    let bytes = self.next_chars_while_len(|c| c != '\n');
8824
                    self.advance_bytes(bytes);
8824
                    if self.src().is_empty() {
1180
                        Ok(Some(Comment::UnclosedLine))
                    } else {
7644
                        Ok(Some(Comment::ClosedLine))
                    }
                }
                '*' => {
22650
                    let mut level = 1;
52352
                    while level > 0 {
205538
                        let bytes = self.next_chars_while_len(|c| !matches!(c, '/' | '*'));
30294
                        if self.src().is_empty() {
298
                            return Err(Error::UnclosedBlockComment);
29996
                        }
29996
                        self.advance_bytes(bytes);
                        // check whether / or * and take action
29996
                        if self.consume_str("/*") {
2058
                            level += 1;
27938
                        } else if self.consume_str("*/") {
24116
                            level -= 1;
24116
                        } else {
3822
                            self.next_char().map_err(|_| Error::UnclosedBlockComment)?;
                        }
                    }
22058
                    Ok(Some(Comment::Block))
                }
294
                c => Err(Error::UnexpectedChar(c)),
            }
        } else {
30767054
            Ok(None)
        }
30798822
    }
}
enum Comment {
    ClosedLine,
    UnclosedLine,
    Block,
}
pub trait Num {
    fn from_u8(x: u8) -> Self;
    /// Returns `true` on overflow
    fn checked_mul_ext(&mut self, x: u8) -> bool;
    /// Returns `true` on overflow
    fn checked_add_ext(&mut self, x: u8) -> bool;
    /// Returns `true` on overflow
    fn checked_sub_ext(&mut self, x: u8) -> bool;
}
macro_rules! impl_num {
    ($ty:ty) => {
        impl Num for $ty {
1394691
            fn from_u8(x: u8) -> Self {
77050
                x as $ty
1394691
            }
579318
            fn checked_mul_ext(&mut self, x: u8) -> bool {
579318
                match self.checked_mul(Self::from_u8(x)) {
578428
                    Some(n) => {
578428
                        *self = n;
578428
                        false
                    }
890
                    None => true,
                }
579318
            }
477710
            fn checked_add_ext(&mut self, x: u8) -> bool {
477710
                match self.checked_add(Self::from_u8(x)) {
477269
                    Some(n) => {
477269
                        *self = n;
477269
                        false
                    }
441
                    None => true,
                }
477710
            }
98660
            fn checked_sub_ext(&mut self, x: u8) -> bool {
98660
                match self.checked_sub(Self::from_u8(x)) {
95720
                    Some(n) => {
95720
                        *self = n;
95720
                        false
                    }
2940
                    None => true,
                }
98660
            }
        }
    };
    ($($tys:ty)*) => {
        $( impl_num!($tys); )*
    };
}
impl_num! { i8 i16 i32 i64 u8 u16 u32 u64 }
#[cfg(feature = "integer128")]
impl_num! { i128 u128 }
pub trait Integer: Sized {
    fn parse(parser: &mut Parser, sign: i8, base: u8) -> Result<Self>;
    fn try_from_parsed_integer(parsed: ParsedInteger, ron: &str) -> Result<Self>;
}
macro_rules! impl_integer {
    ($wrap:ident($ty:ty)) => {
        impl Integer for $ty {
118347
            fn parse(parser: &mut Parser, sign: i8, base: u8) -> Result<Self> {
118347
                parser.parse_integer(sign, base)
118347
            }
34986
            fn try_from_parsed_integer(parsed: ParsedInteger, ron: &str) -> Result<Self> {
34986
                match parsed {
12936
                    ParsedInteger::$wrap(v) => Ok(v),
                    _ => Err(Error::InvalidValueForType {
22050
                        expected: format!(
                            "a{} {}-bit {}signed integer",
22050
                            if <$ty>::BITS == 8 { "n" } else { "n" },
                            <$ty>::BITS,
22050
                            if <$ty>::MIN == 0 { "un" } else { "" },
                        ),
22050
                        found: String::from(ron),
                    }),
                }
34986
            }
        }
    };
    ($($wraps:ident($tys:ty))*) => {
        $( impl_integer!($wraps($tys)); )*
    };
}
impl_integer! {
    I8(i8) I16(i16) I32(i32) I64(i64)
    U8(u8) U16(u16) U32(u32) U64(u64)
}
#[cfg(feature = "integer128")]
impl_integer! { I128(i128) U128(u128) }
pub enum ParsedInteger {
    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    #[cfg(feature = "integer128")]
    I128(i128),
    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    #[cfg(feature = "integer128")]
    U128(u128),
}
impl Integer for ParsedInteger {
84522
    fn parse(parser: &mut Parser, sign: i8, base: u8) -> Result<Self> {
84522
        if sign < 0 {
2108
            let signed = parser.parse_integer::<LargeSInt>(-1, base)?;
614
            return if let Ok(x) = i8::try_from(signed) {
306
                Ok(ParsedInteger::I8(x))
308
            } else if let Ok(x) = i16::try_from(signed) {
4
                Ok(ParsedInteger::I16(x))
304
            } else if let Ok(x) = i32::try_from(signed) {
4
                Ok(ParsedInteger::I32(x))
            } else {
                #[cfg(not(feature = "integer128"))]
                {
2
                    Ok(ParsedInteger::I64(signed))
                }
                #[cfg(feature = "integer128")]
298
                if let Ok(x) = i64::try_from(signed) {
2
                    Ok(ParsedInteger::I64(x))
                } else {
296
                    Ok(ParsedInteger::I128(signed))
                }
            };
82414
        }
82414
        let unsigned = parser.parse_integer::<LargeUInt>(1, base)?;
81667
        if let Ok(x) = u8::try_from(unsigned) {
80767
            Ok(ParsedInteger::U8(x))
900
        } else if let Ok(x) = u16::try_from(unsigned) {
302
            Ok(ParsedInteger::U16(x))
598
        } else if let Ok(x) = u32::try_from(unsigned) {
4
            Ok(ParsedInteger::U32(x))
        } else {
            #[cfg(not(feature = "integer128"))]
            {
2
                Ok(ParsedInteger::U64(unsigned))
            }
            #[cfg(feature = "integer128")]
592
            if let Ok(x) = u64::try_from(unsigned) {
2
                Ok(ParsedInteger::U64(x))
            } else {
590
                Ok(ParsedInteger::U128(unsigned))
            }
        }
84522
    }
233142
    fn try_from_parsed_integer(parsed: ParsedInteger, _ron: &str) -> Result<Self> {
233142
        Ok(parsed)
233142
    }
}
pub trait Float: Sized {
    fn parse(float: &str) -> Result<Self>;
    fn try_from_parsed_float(parsed: ParsedFloat, ron: &str) -> Result<Self>;
}
macro_rules! impl_float {
    ($wrap:ident($ty:ty: $bits:expr)) => {
        impl Float for $ty {
37323
            fn parse(float: &str) -> Result<Self> {
37323
                <$ty>::from_str(float).map_err(|_| Error::ExpectedFloat)
37323
            }
4116
            fn try_from_parsed_float(parsed: ParsedFloat, ron: &str) -> Result<Self> {
4116
                match parsed {
3528
                    ParsedFloat::$wrap(v) => Ok(v),
588
                    _ => Err(Error::InvalidValueForType {
588
                        expected: format!(
588
                            "a {}-bit floating point number", $bits,
588
                        ),
588
                        found: String::from(ron),
588
                    }),
                }
4116
            }
        }
    };
    ($($wraps:ident($tys:ty: $bits:expr))*) => {
        $( impl_float!($wraps($tys: $bits)); )*
    };
}
impl_float! { F32(f32: 32) F64(f64: 64) }
pub enum ParsedFloat {
    F32(f32),
    F64(f64),
}
impl Float for ParsedFloat {
9126162
    fn parse(float: &str) -> Result<Self> {
9126162
        let value = f64::from_str(float).map_err(|_| Error::ExpectedFloat)?;
        #[allow(clippy::cast_possible_truncation)]
9126162
        if value.total_cmp(&f64::from(value as f32)).is_eq() {
4780
            Ok(ParsedFloat::F32(value as f32))
        } else {
9121382
            Ok(ParsedFloat::F64(value))
        }
9126162
    }
2940
    fn try_from_parsed_float(parsed: ParsedFloat, _ron: &str) -> Result<Self> {
2940
        Ok(parsed)
2940
    }
}
pub enum StructType {
    AnyTuple,
    EmptyTuple,
    NewtypeTuple,
    NonNewtypeTuple,
    Named,
    Unit,
}
#[derive(Copy, Clone)] // GRCOV_EXCL_LINE
pub enum NewtypeMode {
    NoParensMeanUnit,
    InsideNewtype,
}
#[derive(Copy, Clone)] // GRCOV_EXCL_LINE
pub enum TupleMode {
    ImpreciseTupleOrNewtype,
    DifferentiateNewtype,
}
pub enum ParsedStr<'a> {
    Allocated(String),
    Slice(&'a str),
}
pub enum ParsedByteStr<'a> {
    Allocated(Vec<u8>),
    Slice(&'a [u8]),
}
impl<'a> ParsedStr<'a> {
92121
    pub fn try_from_bytes(bytes: ParsedByteStr<'a>) -> Result<Self, Utf8Error> {
92121
        match bytes {
8840
            ParsedByteStr::Allocated(byte_buf) => Ok(ParsedStr::Allocated(
8840
                String::from_utf8(byte_buf).map_err(|e| e.utf8_error())?,
            )),
83281
            ParsedByteStr::Slice(bytes) => Ok(ParsedStr::Slice(from_utf8(bytes)?)),
        }
92121
    }
}
impl<'a> ParsedByteStr<'a> {
20
    pub fn try_from_base64(str: &ParsedStr<'a>) -> Option<Self> {
        // Adapted from MIT licensed Jenin Sutradhar's base 64 decoder
        // https://github.com/JeninSutradhar/base64-Rust-Encoder-Decoder/blob/ee1fb08cbb78024ec8cf5e786815acb239169f02/src/lib.rs#L84-L128
20
        fn try_decode_base64(str: &str) -> Option<Vec<u8>> {
            const CHARSET: &[u8; 64] =
                b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
            const PADDING: u8 = b'=';
            // fast reject for missing padding
20
            if (str.len() % 4) != 0 {
4
                return None;
16
            }
16
            let bstr_no_padding = str.trim_end_matches(char::from(PADDING)).as_bytes();
            // fast reject for excessive padding
16
            if (str.len() - bstr_no_padding.len()) > 2 {
                return None;
16
            }
            // fast reject for extraneous bytes after padding
16
            if bstr_no_padding.contains(&PADDING) {
                return None;
16
            }
            // fast reject for non-ASCII
16
            if !str.is_ascii() {
                return None;
16
            }
16
            let mut collected_bits = 0_u8;
16
            let mut byte_buffer = 0_u16;
16
            let mut bytes = bstr_no_padding.iter().copied();
16
            let mut binary = Vec::new();
            'decodeloop: loop {
304
                while collected_bits < 8 {
184
                    if let Some(nextbyte) = bytes.next() {
                        #[allow(clippy::cast_possible_truncation)]
5424
                        if let Some(idx) = CHARSET.iter().position(|&x| x == nextbyte) {
168
                            byte_buffer |= ((idx & 0b0011_1111) as u16) << (10 - collected_bits);
168
                            collected_bits += 6;
168
                        } else {
                            return None;
                        }
                    } else {
16
                        break 'decodeloop;
                    }
                }
120
                binary.push(((0b1111_1111_0000_0000 & byte_buffer) >> 8) as u8);
120
                byte_buffer &= 0b0000_0000_1111_1111;
120
                byte_buffer <<= 8;
120
                collected_bits -= 8;
            }
16
            if usize::from(collected_bits) != ((str.len() - bstr_no_padding.len()) * 2) {
                return None;
16
            }
16
            Some(binary)
20
        }
20
        let base64_str = match str {
            ParsedStr::Allocated(string) => string.as_str(),
20
            ParsedStr::Slice(str) => str,
        };
20
        try_decode_base64(base64_str).map(ParsedByteStr::Allocated)
20
    }
}
#[derive(Copy, Clone)] // GRCOV_EXCL_LINE
enum EscapeEncoding {
    Binary,
    Utf8,
}
enum EscapeCharacter {
    Ascii(u8),
    Utf8(char),
}
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
4
    fn decode_x10() {
4
        let mut bytes = Parser::new("10").unwrap();
4
        assert_eq!(bytes.decode_ascii_escape(), Ok(b'\x10'));
4
    }
    #[test]
4
    fn track_prior_ws() {
        const SOURCE: &str = "   /*hey*/ 42       /*bye*/ 24  ";
4
        let mut bytes = Parser::new(SOURCE).unwrap();
4
        assert_eq!(bytes.src(), "42       /*bye*/ 24  ");
4
        assert_eq!(bytes.pre_ws_src(), SOURCE);
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "42       /*bye*/ 24  ");
4
        assert_eq!(bytes.pre_ws_src(), SOURCE);
4
        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
4
        assert_eq!(bytes.src(), "       /*bye*/ 24  ");
4
        assert_eq!(bytes.pre_ws_src(), SOURCE);
4
        bytes.skip_ws().unwrap();
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "24  ");
4
        assert_eq!(bytes.pre_ws_src(), "       /*bye*/ 24  ");
4
        let mut bytes = Parser::new("42").unwrap();
4
        bytes.skip_ws().unwrap();
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "42");
4
        assert_eq!(bytes.pre_ws_src(), "42");
4
        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
4
        bytes.skip_ws().unwrap();
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "");
4
        assert_eq!(bytes.pre_ws_src(), "");
4
        let mut bytes = Parser::new("  42  ").unwrap();
4
        bytes.skip_ws().unwrap();
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "42  ");
4
        assert_eq!(bytes.pre_ws_src(), "  42  ");
4
        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
4
        bytes.skip_ws().unwrap();
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "");
4
        assert_eq!(bytes.pre_ws_src(), "  ");
4
        let mut bytes = Parser::new("  42  //").unwrap();
4
        bytes.skip_ws().unwrap();
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "42  //");
4
        assert_eq!(bytes.pre_ws_src(), "  42  //");
4
        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
4
        bytes.skip_ws().unwrap();
4
        bytes.skip_ws().unwrap();
4
        assert_eq!(bytes.src(), "");
4
        assert_eq!(bytes.pre_ws_src(), "  //");
4
    }
    #[test]
4
    fn parser_cursor_eq_cmp() {
4
        assert!(
4
            ParserCursor {
4
                cursor: 42,
4
                pre_ws_cursor: 42,
4
                last_ws_len: 42
4
            } == ParserCursor {
4
                cursor: 42,
4
                pre_ws_cursor: 24,
4
                last_ws_len: 24
4
            }
        );
4
        assert!(
4
            ParserCursor {
4
                cursor: 42,
4
                pre_ws_cursor: 42,
4
                last_ws_len: 42
4
            } != ParserCursor {
4
                cursor: 24,
4
                pre_ws_cursor: 42,
4
                last_ws_len: 42
4
            }
        );
4
        assert!(
4
            ParserCursor {
4
                cursor: 42,
4
                pre_ws_cursor: 42,
4
                last_ws_len: 42
4
            } < ParserCursor {
4
                cursor: 43,
4
                pre_ws_cursor: 24,
4
                last_ws_len: 24
4
            }
        );
4
        assert!(
4
            ParserCursor {
4
                cursor: 42,
4
                pre_ws_cursor: 42,
4
                last_ws_len: 42
4
            } > ParserCursor {
4
                cursor: 41,
4
                pre_ws_cursor: 24,
4
                last_ws_len: 24
4
            }
        );
4
    }
    #[test]
4
    fn empty_src_is_not_a_float() {
4
        assert!(!Parser::new("").unwrap().next_bytes_is_float());
4
    }
    #[test]
4
    fn base64_deprecation_error() {
4
        let err = crate::from_str::<bytes::Bytes>("\"SGVsbG8gcm9uIQ==\"").unwrap_err();
4
        assert_eq!(
            err,
4
            SpannedError {
4
                code: Error::InvalidValueForType {
4
                    expected: String::from("the Rusty byte string b\"Hello ron!\""),
4
                    found: String::from("the ambiguous base64 string \"SGVsbG8gcm9uIQ==\"")
4
                },
4
                span: Span {
4
                    start: Position { line: 1, col: 2 },
4
                    end: Position { line: 1, col: 19 },
4
                }
4
            }
        );
4
        let err = crate::from_str::<bytes::Bytes>("r\"SGVsbG8gcm9uIQ==\"").unwrap_err();
4
        assert_eq!(format!("{}", err.code), "Expected the Rusty byte string b\"Hello ron!\" but found the ambiguous base64 string \"SGVsbG8gcm9uIQ==\" instead");
4
        assert_eq!(
4
            crate::from_str::<bytes::Bytes>("\"invalid=\"").unwrap_err(),
4
            SpannedError {
4
                code: Error::InvalidValueForType {
4
                    expected: String::from("the Rusty byte string b\"\\x8a{\\xda\\x96\\'\""),
4
                    found: String::from("the ambiguous base64 string \"invalid=\"")
4
                },
4
                span: Span {
4
                    start: Position { line: 1, col: 2 },
4
                    end: Position { line: 1, col: 11 },
4
                }
4
            }
        );
4
        assert_eq!(
4
            crate::from_str::<bytes::Bytes>("r\"invalid=\"").unwrap_err(),
4
            SpannedError {
4
                code: Error::InvalidValueForType {
4
                    expected: String::from("the Rusty byte string b\"\\x8a{\\xda\\x96\\'\""),
4
                    found: String::from("the ambiguous base64 string \"invalid=\"")
4
                },
4
                span: Span {
4
                    start: Position { line: 1, col: 3 },
4
                    end: Position { line: 1, col: 12 },
4
                }
4
            }
        );
4
        assert_eq!(
4
            crate::from_str::<bytes::Bytes>("r\"invalid\"").unwrap_err(),
            SpannedError {
                code: Error::ExpectedByteString,
                span: Span {
                    start: Position { line: 1, col: 3 },
                    end: Position { line: 1, col: 11 },
                }
            }
        );
4
    }
}