ron/
parse.rs

1#![allow(clippy::identity_op)]
2
3use alloc::{
4    format,
5    string::{String, ToString},
6    vec::Vec,
7};
8use core::{
9    char::from_u32 as char_from_u32,
10    str::{self, from_utf8, FromStr, Utf8Error},
11};
12
13use unicode_ident::{is_xid_continue, is_xid_start};
14
15use crate::{
16    error::{Error, Position, Result, Span, SpannedError, SpannedResult},
17    extensions::Extensions,
18    value::Number,
19};
20
21const fn is_int_char(c: char) -> bool {
22    c.is_ascii_hexdigit() || c == '_'
23}
24
25const fn is_float_char(c: char) -> bool {
26    c.is_ascii_digit() || matches!(c, 'e' | 'E' | '.' | '+' | '-' | '_')
27}
28
29pub fn is_ident_first_char(c: char) -> bool {
30    c == '_' || is_xid_start(c)
31}
32
33pub fn is_ident_raw_char(c: char) -> bool {
34    matches!(c, '.' | '+' | '-') | is_xid_continue(c)
35}
36
37pub const fn is_whitespace_char(c: char) -> bool {
38    matches!(
39        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}
52
53#[cfg(feature = "integer128")]
54pub(crate) type LargeUInt = u128;
55#[cfg(not(feature = "integer128"))]
56pub(crate) type LargeUInt = u64;
57#[cfg(feature = "integer128")]
58pub(crate) type LargeSInt = i128;
59#[cfg(not(feature = "integer128"))]
60pub(crate) type LargeSInt = i64;
61
62pub 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
71pub struct ParserCursor {
72    cursor: usize,
73    pre_ws_cursor: usize,
74    last_ws_len: usize,
75}
76
77const WS_CURSOR_UNCLOSED_LINE: usize = usize::MAX;
78
79impl PartialEq for ParserCursor {
80    fn eq(&self, other: &Self) -> bool {
81        self.cursor == other.cursor
82    }
83}
84
85impl PartialOrd for ParserCursor {
86    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
87        self.cursor.partial_cmp(&other.cursor)
88    }
89}
90
91/// constructor and parsing utilities
92impl<'a> Parser<'a> {
93    pub fn new(src: &'a str) -> SpannedResult<Self> {
94        let mut parser = Parser {
95            exts: Extensions::empty(),
96            src,
97            cursor: ParserCursor {
98                cursor: 0,
99                pre_ws_cursor: 0,
100                last_ws_len: 0,
101            },
102            prev_cursor: ParserCursor {
103                cursor: 0,
104                pre_ws_cursor: 0,
105                last_ws_len: 0,
106            },
107        };
108
109        parser.skip_ws().map_err(|e| parser.span_error(e))?;
110
111        // Loop over all extensions attributes
112        loop {
113            let attribute = parser.extensions().map_err(|e| parser.span_error(e))?;
114
115            if attribute.is_empty() {
116                break;
117            }
118
119            parser.exts |= attribute;
120            parser.skip_ws().map_err(|e| parser.span_error(e))?;
121        }
122
123        Ok(parser)
124    }
125
126    fn set_cursor(&mut self, cursor: ParserCursor) {
127        self.cursor = cursor;
128    }
129
130    pub fn span_error(&self, code: Error) -> SpannedError {
131        SpannedError {
132            code,
133            span: Span {
134                start: Position::from_src_end(&self.src[..self.prev_cursor.cursor]),
135                end: Position::from_src_end(&self.src[..self.cursor.cursor]),
136            },
137        }
138    }
139
140    pub fn advance_bytes(&mut self, bytes: usize) {
141        self.prev_cursor = self.cursor;
142        self.cursor.cursor += bytes;
143    }
144
145    pub fn next_char(&mut self) -> Result<char> {
146        let c = self.peek_char_or_eof()?;
147        self.cursor.cursor += c.len_utf8();
148        Ok(c)
149    }
150
151    pub fn skip_next_char(&mut self) {
152        core::mem::drop(self.next_char());
153    }
154
155    pub fn peek_char(&self) -> Option<char> {
156        self.src().chars().next()
157    }
158
159    pub fn peek_char_or_eof(&self) -> Result<char> {
160        self.peek_char().ok_or(Error::Eof)
161    }
162
163    pub fn check_char(&self, c: char) -> bool {
164        self.src().starts_with(c)
165    }
166
167    pub fn check_str(&self, s: &str) -> bool {
168        self.src().starts_with(s)
169    }
170
171    pub fn src(&self) -> &'a str {
172        &self.src[self.cursor.cursor..]
173    }
174
175    pub fn pre_ws_src(&self) -> &'a str {
176        &self.src[self.cursor.pre_ws_cursor..]
177    }
178
179    pub fn consume_str(&mut self, s: &str) -> bool {
180        if self.check_str(s) {
181            self.advance_bytes(s.len());
182
183            true
184        } else {
185            false
186        }
187    }
188
189    pub fn consume_char(&mut self, c: char) -> bool {
190        if self.check_char(c) {
191            self.advance_bytes(c.len_utf8());
192
193            true
194        } else {
195            false
196        }
197    }
198
199    fn consume_all(&mut self, all: &[&str]) -> Result<bool> {
200        all.iter()
201            .map(|elem| {
202                if self.consume_str(elem) {
203                    self.skip_ws()?;
204
205                    Ok(true)
206                } else {
207                    Ok(false)
208                }
209            })
210            .try_fold(true, |acc, x| x.map(|x| x && acc))
211    }
212
213    pub fn expect_char(&mut self, expected: char, error: Error) -> Result<()> {
214        if self.consume_char(expected) {
215            Ok(())
216        } else {
217            Err(error)
218        }
219    }
220
221    #[must_use]
222    pub fn next_chars_while_len(&self, condition: fn(char) -> bool) -> usize {
223        self.next_chars_while_from_len(0, condition)
224    }
225
226    #[must_use]
227    pub fn next_chars_while_from_len(&self, from: usize, condition: fn(char) -> bool) -> usize {
228        self.src()[from..]
229            .find(|c| !condition(c))
230            .unwrap_or(self.src().len() - from)
231    }
232}
233
234/// actual parsing of ron tokens
235impl<'a> Parser<'a> {
236    fn parse_integer_digits<T: Num>(
237        &mut self,
238        s: &str,
239        base: u8,
240        f: fn(&mut T, u8) -> bool,
241    ) -> Result<T> {
242        let mut num_acc = T::from_u8(0);
243
244        for (i, c) in s.char_indices() {
245            if c == '_' {
246                continue;
247            }
248
249            if num_acc.checked_mul_ext(base) {
250                self.advance_bytes(s.len());
251                return Err(Error::IntegerOutOfBounds);
252            }
253
254            let digit = Self::decode_hex(c)?;
255
256            if digit >= base {
257                self.advance_bytes(i);
258                return Err(Error::InvalidIntegerDigit { digit: c, base });
259            }
260
261            if f(&mut num_acc, digit) {
262                self.advance_bytes(s.len());
263                return Err(Error::IntegerOutOfBounds);
264            }
265        }
266
267        self.advance_bytes(s.len());
268
269        Ok(num_acc)
270    }
271
272    fn parse_integer<T: Num>(&mut self, sign: i8) -> Result<T> {
273        let base = match () {
274            () if self.consume_str("0b") => 2,
275            () if self.consume_str("0o") => 8,
276            () if self.consume_str("0x") => 16,
277            () => 10,
278        };
279
280        let num_bytes = self.next_chars_while_len(is_int_char);
281
282        if num_bytes == 0 {
283            return Err(Error::ExpectedInteger);
284        }
285
286        if self.check_char('_') {
287            return Err(Error::UnderscoreAtBeginning);
288        }
289
290        let s = &self.src()[..num_bytes];
291
292        if sign > 0 {
293            self.parse_integer_digits(s, base, T::checked_add_ext)
294        } else {
295            self.parse_integer_digits(s, base, T::checked_sub_ext)
296        }
297    }
298
299    #[allow(clippy::too_many_lines)]
300    pub fn integer<T: Integer>(&mut self) -> Result<T> {
301        let src_backup = self.src();
302
303        let is_negative = match self.peek_char_or_eof()? {
304            '+' => {
305                self.skip_next_char();
306                false
307            }
308            '-' => {
309                self.skip_next_char();
310                true
311            }
312            'b' if self.consume_str("b'") => {
313                // Parse a byte literal
314                let byte = match self.next_char()? {
315                    '\\' => match self.parse_escape(EscapeEncoding::Binary, true)? {
316                        // we know that this byte is an ASCII character
317                        EscapeCharacter::Ascii(b) => b,
318                        EscapeCharacter::Utf8(_) => {
319                            return Err(Error::InvalidEscape(
320                                "Unexpected Unicode escape in byte literal",
321                            ))
322                        }
323                    },
324                    b if b.is_ascii() => b as u8,
325                    _ => return Err(Error::ExpectedByteLiteral),
326                };
327
328                if !self.consume_char('\'') {
329                    return Err(Error::ExpectedByteLiteral);
330                }
331
332                let bytes_ron = &src_backup[..src_backup.len() - self.src().len()];
333
334                return T::try_from_parsed_integer(ParsedInteger::U8(byte), bytes_ron);
335            }
336            _ => false,
337        };
338        let sign = if is_negative { -1 } else { 1 };
339
340        let num_bytes = self.next_chars_while_len(is_int_char);
341
342        if self.src()[num_bytes..].starts_with(['i', 'u']) {
343            let int_cursor = self.cursor;
344            self.advance_bytes(num_bytes);
345
346            #[allow(clippy::never_loop)]
347            loop {
348                let (res, suffix_bytes) = if self.consume_ident("i8") {
349                    let suffix_bytes = self.src();
350                    self.set_cursor(int_cursor);
351                    (
352                        self.parse_integer::<i8>(sign).map(ParsedInteger::I8),
353                        suffix_bytes,
354                    )
355                } else if self.consume_ident("i16") {
356                    let suffix_bytes = self.src();
357                    self.set_cursor(int_cursor);
358                    (
359                        self.parse_integer::<i16>(sign).map(ParsedInteger::I16),
360                        suffix_bytes,
361                    )
362                } else if self.consume_ident("i32") {
363                    let suffix_bytes = self.src();
364                    self.set_cursor(int_cursor);
365                    (
366                        self.parse_integer::<i32>(sign).map(ParsedInteger::I32),
367                        suffix_bytes,
368                    )
369                } else if self.consume_ident("i64") {
370                    let suffix_bytes = self.src();
371                    self.set_cursor(int_cursor);
372                    (
373                        self.parse_integer::<i64>(sign).map(ParsedInteger::I64),
374                        suffix_bytes,
375                    )
376                } else if self.consume_ident("u8") {
377                    let suffix_bytes = self.src();
378                    self.set_cursor(int_cursor);
379                    (
380                        self.parse_integer::<u8>(sign).map(ParsedInteger::U8),
381                        suffix_bytes,
382                    )
383                } else if self.consume_ident("u16") {
384                    let suffix_bytes = self.src();
385                    self.set_cursor(int_cursor);
386                    (
387                        self.parse_integer::<u16>(sign).map(ParsedInteger::U16),
388                        suffix_bytes,
389                    )
390                } else if self.consume_ident("u32") {
391                    let suffix_bytes = self.src();
392                    self.set_cursor(int_cursor);
393                    (
394                        self.parse_integer::<u32>(sign).map(ParsedInteger::U32),
395                        suffix_bytes,
396                    )
397                } else if self.consume_ident("u64") {
398                    let suffix_bytes = self.src();
399                    self.set_cursor(int_cursor);
400                    (
401                        self.parse_integer::<u64>(sign).map(ParsedInteger::U64),
402                        suffix_bytes,
403                    )
404                } else {
405                    #[cfg(feature = "integer128")]
406                    if self.consume_ident("i128") {
407                        let suffix_bytes = self.src();
408                        self.set_cursor(int_cursor);
409                        (
410                            self.parse_integer::<i128>(sign).map(ParsedInteger::I128),
411                            suffix_bytes,
412                        )
413                    } else if self.consume_ident("u128") {
414                        let suffix_bytes = self.src();
415                        self.set_cursor(int_cursor);
416                        (
417                            self.parse_integer::<u128>(sign).map(ParsedInteger::U128),
418                            suffix_bytes,
419                        )
420                    } else {
421                        break;
422                    }
423                    #[cfg(not(feature = "integer128"))]
424                    {
425                        break;
426                    }
427                };
428
429                if !matches!(
430                    &res,
431                    Err(Error::UnderscoreAtBeginning | Error::InvalidIntegerDigit { .. })
432                ) {
433                    // Advance past the number suffix
434                    self.skip_identifier();
435                }
436
437                let integer_ron = &src_backup[..src_backup.len() - suffix_bytes.len()];
438
439                return res.and_then(|parsed| T::try_from_parsed_integer(parsed, integer_ron));
440            }
441
442            self.set_cursor(int_cursor);
443        }
444
445        T::parse(self, sign)
446    }
447
448    pub fn any_number(&mut self) -> Result<Number> {
449        if self.next_bytes_is_float() {
450            return match self.float::<ParsedFloat>()? {
451                ParsedFloat::F32(v) => Ok(Number::F32(v.into())),
452                ParsedFloat::F64(v) => Ok(Number::F64(v.into())),
453            };
454        }
455
456        let backup_cursor = self.cursor;
457
458        let (integer_err, integer_cursor) = match self.integer::<ParsedInteger>() {
459            Ok(integer) => {
460                return match integer {
461                    ParsedInteger::I8(v) => Ok(Number::I8(v)),
462                    ParsedInteger::I16(v) => Ok(Number::I16(v)),
463                    ParsedInteger::I32(v) => Ok(Number::I32(v)),
464                    ParsedInteger::I64(v) => Ok(Number::I64(v)),
465                    #[cfg(feature = "integer128")]
466                    ParsedInteger::I128(v) => Ok(Number::I128(v)),
467                    ParsedInteger::U8(v) => Ok(Number::U8(v)),
468                    ParsedInteger::U16(v) => Ok(Number::U16(v)),
469                    ParsedInteger::U32(v) => Ok(Number::U32(v)),
470                    ParsedInteger::U64(v) => Ok(Number::U64(v)),
471                    #[cfg(feature = "integer128")]
472                    ParsedInteger::U128(v) => Ok(Number::U128(v)),
473                }
474            }
475            Err(err) => (err, self.cursor),
476        };
477
478        self.set_cursor(backup_cursor);
479
480        // Fall-back to parse an out-of-range integer as a float
481        match self.float::<ParsedFloat>() {
482            Ok(ParsedFloat::F32(v)) if self.cursor >= integer_cursor => Ok(Number::F32(v.into())),
483            Ok(ParsedFloat::F64(v)) if self.cursor >= integer_cursor => Ok(Number::F64(v.into())),
484            _ => {
485                // Return the more precise integer error
486                self.set_cursor(integer_cursor);
487                Err(integer_err)
488            }
489        }
490    }
491
492    pub fn bool(&mut self) -> Result<bool> {
493        if self.consume_ident("true") {
494            Ok(true)
495        } else if self.consume_ident("false") {
496            Ok(false)
497        } else {
498            Err(Error::ExpectedBoolean)
499        }
500    }
501
502    pub fn char(&mut self) -> Result<char> {
503        self.expect_char('\'', Error::ExpectedChar)?;
504
505        let c = self.next_char()?;
506
507        let c = if c == '\\' {
508            match self.parse_escape(EscapeEncoding::Utf8, true)? {
509                // we know that this byte is an ASCII character
510                EscapeCharacter::Ascii(b) => char::from(b),
511                EscapeCharacter::Utf8(c) => c,
512            }
513        } else {
514            c
515        };
516
517        self.expect_char('\'', Error::ExpectedChar)?;
518
519        Ok(c)
520    }
521
522    pub fn comma(&mut self) -> Result<bool> {
523        self.skip_ws()?;
524
525        if self.consume_char(',') {
526            self.skip_ws()?;
527
528            Ok(true)
529        } else {
530            Ok(false)
531        }
532    }
533
534    /// Only returns true if the char after `ident` cannot belong
535    /// to an identifier.
536    pub fn check_ident(&mut self, ident: &str) -> bool {
537        self.check_str(ident) && !self.check_ident_other_char(ident.len())
538    }
539
540    fn check_ident_other_char(&self, index: usize) -> bool {
541        self.src()[index..]
542            .chars()
543            .next()
544            .map_or(false, is_xid_continue)
545    }
546
547    /// Check which type of struct we are currently parsing. The parsing state
548    ///  is only changed in case of an error, to provide a better position.
549    ///
550    /// [`NewtypeMode::NoParensMeanUnit`] detects (tuple) structs by a leading
551    ///  opening bracket and reports a unit struct otherwise.
552    /// [`NewtypeMode::InsideNewtype`] skips an initial check for unit structs,
553    ///  and means that any leading opening bracket is not considered to open
554    ///  a (tuple) struct but to be part of the structs inner contents.
555    ///
556    /// [`TupleMode::ImpreciseTupleOrNewtype`] only performs a cheap, O(1),
557    ///  single-identifier lookahead check to distinguish tuple structs from
558    ///  non-tuple structs.
559    /// [`TupleMode::DifferentiateNewtype`] performs an expensive, O(N), look-
560    ///  ahead over the entire next value tree, which can span the entirety of
561    ///  the remaining document in the worst case.
562    pub fn check_struct_type(
563        &mut self,
564        newtype: NewtypeMode,
565        tuple: TupleMode,
566    ) -> Result<StructType> {
567        fn check_struct_type_inner(
568            parser: &mut Parser,
569            newtype: NewtypeMode,
570            tuple: TupleMode,
571        ) -> Result<StructType> {
572            if matches!(newtype, NewtypeMode::NoParensMeanUnit) && !parser.consume_char('(') {
573                return Ok(StructType::Unit);
574            }
575
576            parser.skip_ws()?;
577
578            // Check for `Ident()`, which could be
579            // - a zero-field struct or tuple (variant)
580            // - an unwrapped newtype around a unit
581            if matches!(newtype, NewtypeMode::NoParensMeanUnit) && parser.check_char(')') {
582                return Ok(StructType::EmptyTuple);
583            }
584
585            if parser.skip_identifier().is_some() {
586                parser.skip_ws()?;
587
588                match parser.peek_char() {
589                    // Definitely a struct with named fields
590                    Some(':') => return Ok(StructType::Named),
591                    // Definitely a tuple-like struct with fields
592                    Some(',') => {
593                        parser.skip_next_char();
594                        parser.skip_ws()?;
595                        if parser.check_char(')') {
596                            // A one-element tuple could be a newtype
597                            return Ok(StructType::NewtypeTuple);
598                        }
599                        // Definitely a tuple struct with more than one field
600                        return Ok(StructType::NonNewtypeTuple);
601                    }
602                    // Either a newtype or a tuple struct
603                    Some(')') => return Ok(StructType::NewtypeTuple),
604                    // Something else, let's investigate further
605                    Some(_) | None => (),
606                };
607            }
608
609            if matches!(tuple, TupleMode::ImpreciseTupleOrNewtype) {
610                return Ok(StructType::AnyTuple);
611            }
612
613            let mut braces = 1_usize;
614            let mut more_than_one = false;
615
616            // Skip ahead to see if the value is followed by another value
617            while braces > 0 {
618                // Skip spurious braces in comments, strings, and characters
619                parser.skip_ws()?;
620                let cursor_backup = parser.cursor;
621                if parser.char().is_err() {
622                    parser.set_cursor(cursor_backup);
623                }
624                let cursor_backup = parser.cursor;
625                match parser.string() {
626                    Ok(_) => (),
627                    // prevent quadratic complexity backtracking for unterminated string
628                    Err(err @ (Error::ExpectedStringEnd | Error::Eof)) => return Err(err),
629                    Err(_) => parser.set_cursor(cursor_backup),
630                }
631                let cursor_backup = parser.cursor;
632                // we have already checked for strings, which subsume base64 byte strings
633                match parser.byte_string_no_base64() {
634                    Ok(_) => (),
635                    // prevent quadratic complexity backtracking for unterminated byte string
636                    Err(err @ (Error::ExpectedStringEnd | Error::Eof)) => return Err(err),
637                    Err(_) => parser.set_cursor(cursor_backup),
638                }
639
640                let c = parser.next_char()?;
641                if matches!(c, '(' | '[' | '{') {
642                    braces += 1;
643                } else if matches!(c, ')' | ']' | '}') {
644                    braces -= 1;
645                } else if c == ',' && braces == 1 {
646                    parser.skip_ws()?;
647                    more_than_one = !parser.check_char(')');
648                    break;
649                }
650            }
651
652            if more_than_one {
653                Ok(StructType::NonNewtypeTuple)
654            } else {
655                Ok(StructType::NewtypeTuple)
656            }
657        }
658
659        // Create a temporary working copy
660        let backup_cursor = self.cursor;
661
662        let result = check_struct_type_inner(self, newtype, tuple);
663
664        if result.is_ok() {
665            // Revert the parser to before the struct type check
666            self.set_cursor(backup_cursor);
667        }
668
669        result
670    }
671
672    /// Only returns true if the char after `ident` cannot belong
673    /// to an identifier.
674    pub fn consume_ident(&mut self, ident: &str) -> bool {
675        if self.check_ident(ident) {
676            self.advance_bytes(ident.len());
677
678            true
679        } else {
680            false
681        }
682    }
683
684    pub fn consume_struct_name(&mut self, ident: &'static str) -> Result<bool> {
685        if self.check_ident("") {
686            if self.exts.contains(Extensions::EXPLICIT_STRUCT_NAMES) {
687                return Err(Error::ExpectedStructName(ident.to_string()));
688            }
689
690            return Ok(false);
691        }
692
693        let found_ident = match self.identifier() {
694            Ok(maybe_ident) => maybe_ident,
695            Err(Error::SuggestRawIdentifier(found_ident)) if found_ident == ident => {
696                return Err(Error::SuggestRawIdentifier(found_ident))
697            }
698            Err(_) => return Err(Error::ExpectedNamedStructLike(ident)),
699        };
700
701        if ident.is_empty() {
702            return Err(Error::ExpectedNamedStructLike(ident));
703        }
704
705        if found_ident != ident {
706            return Err(Error::ExpectedDifferentStructName {
707                expected: ident,
708                found: String::from(found_ident),
709            });
710        }
711
712        Ok(true)
713    }
714
715    /// Returns the extensions bit mask.
716    fn extensions(&mut self) -> Result<Extensions> {
717        if !self.check_char('#') {
718            return Ok(Extensions::empty());
719        }
720
721        if !self.consume_all(&["#", "!", "[", "enable", "("])? {
722            return Err(Error::ExpectedAttribute);
723        }
724
725        self.skip_ws()?;
726        let mut extensions = Extensions::empty();
727
728        loop {
729            let ident = self.identifier()?;
730            let extension = Extensions::from_ident(ident)
731                .ok_or_else(|| Error::NoSuchExtension(ident.into()))?;
732
733            extensions |= extension;
734
735            let comma = self.comma()?;
736
737            // If we have no comma but another item, return an error
738            if !comma && self.check_ident_other_char(0) {
739                return Err(Error::ExpectedComma);
740            }
741
742            // If there's no comma, assume the list ended.
743            // If there is, it might be a trailing one, thus we only
744            // continue the loop if we get an ident char.
745            if !comma || !self.check_ident_other_char(0) {
746                break;
747            }
748        }
749
750        self.skip_ws()?;
751
752        if self.consume_all(&[")", "]"])? {
753            Ok(extensions)
754        } else {
755            Err(Error::ExpectedAttributeEnd)
756        }
757    }
758
759    pub fn float<T: Float>(&mut self) -> Result<T> {
760        const F32_SUFFIX: &str = "f32";
761        const F64_SUFFIX: &str = "f64";
762
763        for (literal, value_f32, value_f64) in &[
764            ("inf", f32::INFINITY, f64::INFINITY),
765            ("+inf", f32::INFINITY, f64::INFINITY),
766            ("-inf", f32::NEG_INFINITY, f64::NEG_INFINITY),
767            ("NaN", f32::NAN, f64::NAN),
768            ("+NaN", f32::NAN, f64::NAN),
769            ("-NaN", -f32::NAN, -f64::NAN),
770        ] {
771            if self.consume_ident(literal) {
772                return T::parse(literal);
773            }
774
775            if let Some(suffix) = self.src().strip_prefix(literal) {
776                if let Some(post_suffix) = suffix.strip_prefix(F32_SUFFIX) {
777                    if !post_suffix.chars().next().map_or(false, is_xid_continue) {
778                        let float_ron = &self.src()[..literal.len() + F32_SUFFIX.len()];
779                        self.advance_bytes(literal.len() + F32_SUFFIX.len());
780                        return T::try_from_parsed_float(ParsedFloat::F32(*value_f32), float_ron);
781                    }
782                }
783
784                if let Some(post_suffix) = suffix.strip_prefix(F64_SUFFIX) {
785                    if !post_suffix.chars().next().map_or(false, is_xid_continue) {
786                        let float_ron = &self.src()[..literal.len() + F64_SUFFIX.len()];
787                        self.advance_bytes(literal.len() + F64_SUFFIX.len());
788                        return T::try_from_parsed_float(ParsedFloat::F64(*value_f64), float_ron);
789                    }
790                }
791            }
792        }
793
794        let num_bytes = self.next_chars_while_len(is_float_char);
795
796        if num_bytes == 0 {
797            return Err(Error::ExpectedFloat);
798        }
799
800        if self.check_char('_') {
801            return Err(Error::UnderscoreAtBeginning);
802        }
803
804        let mut f = String::with_capacity(num_bytes);
805        let mut allow_underscore = false;
806
807        for (i, c) in self.src()[..num_bytes].char_indices() {
808            match c {
809                '_' if allow_underscore => continue,
810                '_' => {
811                    self.advance_bytes(i);
812                    return Err(Error::FloatUnderscore);
813                }
814                '0'..='9' | 'e' | 'E' => allow_underscore = true,
815                '.' => allow_underscore = false,
816                _ => (),
817            }
818
819            // we know that the byte is an ASCII character here
820            f.push(c);
821        }
822
823        if self.src()[num_bytes..].starts_with('f') {
824            let backup_cursor = self.cursor;
825            self.advance_bytes(num_bytes);
826
827            #[allow(clippy::never_loop)]
828            loop {
829                let res = if self.consume_ident(F32_SUFFIX) {
830                    f32::from_str(&f).map(ParsedFloat::F32)
831                } else if self.consume_ident(F64_SUFFIX) {
832                    f64::from_str(&f).map(ParsedFloat::F64)
833                } else {
834                    break;
835                };
836
837                let parsed = if let Ok(parsed) = res {
838                    parsed
839                } else {
840                    self.set_cursor(backup_cursor);
841                    return Err(Error::ExpectedFloat);
842                };
843
844                let float_ron = &self.src[backup_cursor.cursor..self.cursor.cursor];
845
846                return T::try_from_parsed_float(parsed, float_ron);
847            }
848
849            self.set_cursor(backup_cursor);
850        }
851
852        let value = T::parse(&f)?;
853
854        self.advance_bytes(num_bytes);
855
856        Ok(value)
857    }
858
859    pub fn skip_identifier(&mut self) -> Option<&'a str> {
860        #[allow(clippy::nonminimal_bool)]
861        if self.check_str("b\"") // byte string
862            || self.check_str("b'") // byte literal
863            || self.check_str("br#") // raw byte string
864            || self.check_str("br\"") // raw byte string
865            || self.check_str("r\"") // raw string
866            || self.check_str("r#\"") // raw string
867            || self.check_str("r##") // raw string
868            || false
869        {
870            return None;
871        }
872
873        if self.check_str("r#") {
874            // maybe a raw identifier
875            let len = self.next_chars_while_from_len(2, is_ident_raw_char);
876            if len > 0 {
877                let ident = &self.src()[2..2 + len];
878                self.advance_bytes(2 + len);
879                return Some(ident);
880            }
881            return None;
882        }
883
884        if let Some(c) = self.peek_char() {
885            // maybe a normal identifier
886            if is_ident_first_char(c) {
887                let len =
888                    c.len_utf8() + self.next_chars_while_from_len(c.len_utf8(), is_xid_continue);
889                let ident = &self.src()[..len];
890                self.advance_bytes(len);
891                return Some(ident);
892            }
893        }
894
895        None
896    }
897
898    pub fn identifier(&mut self) -> Result<&'a str> {
899        let first = self.peek_char_or_eof()?;
900        if !is_ident_first_char(first) {
901            if is_ident_raw_char(first) {
902                let ident_bytes = self.next_chars_while_len(is_ident_raw_char);
903                return Err(Error::SuggestRawIdentifier(
904                    self.src()[..ident_bytes].into(),
905                ));
906            }
907
908            return Err(Error::ExpectedIdentifier);
909        }
910
911        // If the next 2-3 bytes signify the start of a (raw) (byte) string
912        //  literal, return an error.
913        #[allow(clippy::nonminimal_bool)]
914        if self.check_str("b\"") // byte string
915            || self.check_str("b'") // byte literal
916            || self.check_str("br#") // raw byte string
917            || self.check_str("br\"") // raw byte string
918            || self.check_str("r\"") // raw string
919            || self.check_str("r#\"") // raw string
920            || self.check_str("r##") // raw string
921            || false
922        {
923            return Err(Error::ExpectedIdentifier);
924        }
925
926        let length = if self.check_str("r#") {
927            let cursor_backup = self.cursor;
928
929            self.advance_bytes(2);
930
931            // Note: it's important to check this before advancing forward, so that
932            // the value-type deserializer can fall back to parsing it differently.
933            if !matches!(self.peek_char(), Some(c) if is_ident_raw_char(c)) {
934                self.set_cursor(cursor_backup);
935                return Err(Error::ExpectedIdentifier);
936            }
937
938            self.next_chars_while_len(is_ident_raw_char)
939        } else if first == 'r' {
940            let std_ident_length = self.next_chars_while_len(is_xid_continue);
941            let raw_ident_length = self.next_chars_while_len(is_ident_raw_char);
942
943            if raw_ident_length > std_ident_length {
944                return Err(Error::SuggestRawIdentifier(
945                    self.src()[..raw_ident_length].into(),
946                ));
947            }
948
949            std_ident_length
950        } else {
951            let std_ident_length = first.len_utf8()
952                + self.next_chars_while_from_len(first.len_utf8(), is_xid_continue);
953            let raw_ident_length = self.next_chars_while_len(is_ident_raw_char);
954
955            if raw_ident_length > std_ident_length {
956                return Err(Error::SuggestRawIdentifier(
957                    self.src()[..raw_ident_length].into(),
958                ));
959            }
960
961            std_ident_length
962        };
963
964        let ident = &self.src()[..length];
965        self.advance_bytes(length);
966
967        Ok(ident)
968    }
969
970    pub fn next_bytes_is_float(&mut self) -> bool {
971        if let Some(c) = self.peek_char() {
972            let skip = match c {
973                '+' | '-' => 1,
974                _ => 0,
975            };
976            let valid_float_len = self.next_chars_while_from_len(skip, is_float_char);
977            let valid_int_len = self.next_chars_while_from_len(skip, is_int_char);
978            valid_float_len > valid_int_len
979        } else {
980            false
981        }
982    }
983
984    pub fn skip_ws(&mut self) -> Result<()> {
985        if (self.cursor.last_ws_len != WS_CURSOR_UNCLOSED_LINE)
986            && ((self.cursor.pre_ws_cursor + self.cursor.last_ws_len) < self.cursor.cursor)
987        {
988            // the last whitespace is disjoint from this one, we need to track a new one
989            self.cursor.pre_ws_cursor = self.cursor.cursor;
990        }
991
992        if self.src().is_empty() {
993            return Ok(());
994        }
995
996        loop {
997            self.advance_bytes(self.next_chars_while_len(is_whitespace_char));
998
999            match self.skip_comment()? {
1000                None => break,
1001                Some(Comment::UnclosedLine) => {
1002                    self.cursor.last_ws_len = WS_CURSOR_UNCLOSED_LINE;
1003                    return Ok(());
1004                }
1005                Some(Comment::ClosedLine | Comment::Block) => continue,
1006            }
1007        }
1008
1009        self.cursor.last_ws_len = self.cursor.cursor - self.cursor.pre_ws_cursor;
1010
1011        Ok(())
1012    }
1013
1014    pub fn has_unclosed_line_comment(&self) -> bool {
1015        self.src().is_empty() && self.cursor.last_ws_len == WS_CURSOR_UNCLOSED_LINE
1016    }
1017
1018    pub fn byte_string(&mut self) -> Result<ParsedByteStr<'a>> {
1019        fn expected_byte_string_found_base64(
1020            base64_str: &ParsedStr,
1021            byte_str: &ParsedByteStr,
1022        ) -> Error {
1023            let byte_str = match &byte_str {
1024                ParsedByteStr::Allocated(b) => b.as_slice(),
1025                ParsedByteStr::Slice(b) => b,
1026            }
1027            .iter()
1028            .flat_map(|c| core::ascii::escape_default(*c))
1029            .map(char::from)
1030            .collect::<String>();
1031            let base64_str = match &base64_str {
1032                ParsedStr::Allocated(s) => s.as_str(),
1033                ParsedStr::Slice(s) => s,
1034            };
1035
1036            Error::InvalidValueForType {
1037                expected: format!("the Rusty byte string b\"{}\"", byte_str),
1038                found: format!("the ambiguous base64 string {:?}", base64_str),
1039            }
1040        }
1041
1042        // FIXME @juntyr: remove in v0.13, since only byte_string_no_base64 will
1043        //                be used
1044        if self.consume_char('"') {
1045            let base64_str = self.escaped_string()?;
1046            let base64_result = ParsedByteStr::try_from_base64(&base64_str);
1047
1048            match base64_result {
1049                Some(byte_str) => Err(expected_byte_string_found_base64(&base64_str, &byte_str)),
1050                None => Err(Error::ExpectedByteString),
1051            }
1052        } else if self.consume_char('r') {
1053            let base64_str = self.raw_string()?;
1054            let base64_result = ParsedByteStr::try_from_base64(&base64_str);
1055
1056            match base64_result {
1057                Some(byte_str) => Err(expected_byte_string_found_base64(&base64_str, &byte_str)),
1058                None => Err(Error::ExpectedByteString),
1059            }
1060        } else {
1061            self.byte_string_no_base64()
1062        }
1063    }
1064
1065    pub fn byte_string_no_base64(&mut self) -> Result<ParsedByteStr<'a>> {
1066        if self.consume_str("b\"") {
1067            self.escaped_byte_string()
1068        } else if self.consume_str("br") {
1069            self.raw_byte_string()
1070        } else {
1071            Err(Error::ExpectedByteString)
1072        }
1073    }
1074
1075    fn escaped_byte_string(&mut self) -> Result<ParsedByteStr<'a>> {
1076        match self.escaped_byte_buf(EscapeEncoding::Binary) {
1077            Ok((bytes, advance)) => {
1078                self.advance_bytes(advance);
1079                Ok(bytes)
1080            }
1081            Err(err) => Err(err),
1082        }
1083    }
1084
1085    fn raw_byte_string(&mut self) -> Result<ParsedByteStr<'a>> {
1086        match self.raw_byte_buf() {
1087            Ok((bytes, advance)) => {
1088                self.advance_bytes(advance);
1089                Ok(bytes)
1090            }
1091            Err(Error::ExpectedString) => Err(Error::ExpectedByteString),
1092            Err(err) => Err(err),
1093        }
1094    }
1095
1096    pub fn string(&mut self) -> Result<ParsedStr<'a>> {
1097        if self.consume_char('"') {
1098            self.escaped_string()
1099        } else if self.consume_char('r') {
1100            self.raw_string()
1101        } else {
1102            Err(Error::ExpectedString)
1103        }
1104    }
1105
1106    fn escaped_string(&mut self) -> Result<ParsedStr<'a>> {
1107        match self.escaped_byte_buf(EscapeEncoding::Utf8) {
1108            Ok((bytes, advance)) => {
1109                let string = ParsedStr::try_from_bytes(bytes).map_err(Error::from)?;
1110                self.advance_bytes(advance);
1111                Ok(string)
1112            }
1113            Err(err) => Err(err),
1114        }
1115    }
1116
1117    fn raw_string(&mut self) -> Result<ParsedStr<'a>> {
1118        match self.raw_byte_buf() {
1119            Ok((bytes, advance)) => {
1120                let string = ParsedStr::try_from_bytes(bytes).map_err(Error::from)?;
1121                self.advance_bytes(advance);
1122                Ok(string)
1123            }
1124            Err(err) => Err(err),
1125        }
1126    }
1127
1128    fn escaped_byte_buf(&mut self, encoding: EscapeEncoding) -> Result<(ParsedByteStr<'a>, usize)> {
1129        // Checking for '"' and '\\' separately is faster than searching for both at the same time
1130        let str_end = self.src().find('"').ok_or(Error::ExpectedStringEnd)?;
1131        let escape = self.src()[..str_end].find('\\');
1132
1133        if let Some(escape) = escape {
1134            // Now check if escaping is used inside the string
1135            let mut i = escape;
1136            let mut s = self.src().as_bytes()[..i].to_vec();
1137
1138            loop {
1139                self.advance_bytes(i + 1);
1140
1141                match self.parse_escape(encoding, false)? {
1142                    EscapeCharacter::Ascii(c) => s.push(c),
1143                    EscapeCharacter::Utf8(c) => match c.len_utf8() {
1144                        1 => s.push(c as u8),
1145                        len => {
1146                            let start = s.len();
1147                            s.extend(core::iter::repeat(0).take(len));
1148                            c.encode_utf8(&mut s[start..]);
1149                        }
1150                    },
1151                }
1152
1153                // Checking for '"' and '\\' separately is faster than searching for both at the same time
1154                let new_str_end = self.src().find('"').ok_or(Error::ExpectedStringEnd)?;
1155                let new_escape = self.src()[..new_str_end].find('\\');
1156
1157                if let Some(new_escape) = new_escape {
1158                    s.extend_from_slice(&self.src().as_bytes()[..new_escape]);
1159                    i = new_escape;
1160                } else {
1161                    s.extend_from_slice(&self.src().as_bytes()[..new_str_end]);
1162                    // Advance to the end of the string + 1 for the `"`.
1163                    break Ok((ParsedByteStr::Allocated(s), new_str_end + 1));
1164                }
1165            }
1166        } else {
1167            let s = &self.src().as_bytes()[..str_end];
1168
1169            // Advance by the number of bytes of the string + 1 for the `"`.
1170            Ok((ParsedByteStr::Slice(s), str_end + 1))
1171        }
1172    }
1173
1174    fn raw_byte_buf(&mut self) -> Result<(ParsedByteStr<'a>, usize)> {
1175        let num_hashes = self.next_chars_while_len(|c| c == '#');
1176        let hashes = &self.src()[..num_hashes];
1177        self.advance_bytes(num_hashes);
1178
1179        self.expect_char('"', Error::ExpectedString)?;
1180
1181        let ending = ["\"", hashes].concat();
1182        let i = self.src().find(&ending).ok_or(Error::ExpectedStringEnd)?;
1183
1184        let s = &self.src().as_bytes()[..i];
1185
1186        // Advance by the number of bytes of the byte string
1187        // + `num_hashes` + 1 for the `"`.
1188        Ok((ParsedByteStr::Slice(s), i + num_hashes + 1))
1189    }
1190
1191    fn decode_ascii_escape(&mut self) -> Result<u8> {
1192        let mut n = 0;
1193        for _ in 0..2 {
1194            n <<= 4;
1195            let byte = self.next_char()?;
1196            let decoded = Self::decode_hex(byte)?;
1197            n |= decoded;
1198        }
1199
1200        Ok(n)
1201    }
1202
1203    #[inline]
1204    fn decode_hex(c: char) -> Result<u8> {
1205        if !c.is_ascii() {
1206            return Err(Error::InvalidEscape("Non-hex digit found"));
1207        }
1208
1209        // c is an ASCII character that can be losslessly cast to u8
1210        match c as u8 {
1211            c @ b'0'..=b'9' => Ok(c - b'0'),
1212            c @ b'a'..=b'f' => Ok(10 + c - b'a'),
1213            c @ b'A'..=b'F' => Ok(10 + c - b'A'),
1214            _ => Err(Error::InvalidEscape("Non-hex digit found")),
1215        }
1216    }
1217
1218    fn parse_escape(&mut self, encoding: EscapeEncoding, is_char: bool) -> Result<EscapeCharacter> {
1219        let c = match self.next_char()? {
1220            '\'' => EscapeCharacter::Ascii(b'\''),
1221            '"' => EscapeCharacter::Ascii(b'"'),
1222            '\\' => EscapeCharacter::Ascii(b'\\'),
1223            'n' => EscapeCharacter::Ascii(b'\n'),
1224            'r' => EscapeCharacter::Ascii(b'\r'),
1225            't' => EscapeCharacter::Ascii(b'\t'),
1226            '0' => EscapeCharacter::Ascii(b'\0'),
1227            'x' => {
1228                // Fast exit for ascii escape in byte string
1229                let b: u8 = self.decode_ascii_escape()?;
1230                if let EscapeEncoding::Binary = encoding {
1231                    return Ok(EscapeCharacter::Ascii(b));
1232                }
1233
1234                // Fast exit for ascii character in UTF-8 string
1235                let mut bytes = [b, 0, 0, 0];
1236                if let Ok(Some(c)) = from_utf8(&bytes[..=0]).map(|s| s.chars().next()) {
1237                    return Ok(EscapeCharacter::Utf8(c));
1238                }
1239
1240                if is_char {
1241                    // Character literals are not allowed to use multiple byte
1242                    //  escapes to build a unicode character
1243                    return Err(Error::InvalidEscape(
1244                        "Not a valid byte-escaped Unicode character",
1245                    ));
1246                }
1247
1248                // UTF-8 character needs up to four bytes and we have already
1249                //  consumed one, so at most three to go
1250                for i in 1..4 {
1251                    if !self.consume_str(r"\x") {
1252                        return Err(Error::InvalidEscape(
1253                            "Not a valid byte-escaped Unicode character",
1254                        ));
1255                    }
1256
1257                    bytes[i] = self.decode_ascii_escape()?;
1258
1259                    // Check if we now have a valid UTF-8 character
1260                    if let Ok(Some(c)) = from_utf8(&bytes[..=i]).map(|s| s.chars().next()) {
1261                        return Ok(EscapeCharacter::Utf8(c));
1262                    }
1263                }
1264
1265                return Err(Error::InvalidEscape(
1266                    "Not a valid byte-escaped Unicode character",
1267                ));
1268            }
1269            'u' => {
1270                self.expect_char('{', Error::InvalidEscape("Missing { in Unicode escape"))?;
1271
1272                let mut bytes: u32 = 0;
1273                let mut num_digits = 0;
1274
1275                while num_digits < 6 {
1276                    let byte = self.peek_char_or_eof()?;
1277
1278                    if byte == '}' {
1279                        break;
1280                    }
1281
1282                    self.skip_next_char();
1283                    num_digits += 1;
1284
1285                    let byte = Self::decode_hex(byte)?;
1286                    bytes <<= 4;
1287                    bytes |= u32::from(byte);
1288                }
1289
1290                if num_digits == 0 {
1291                    return Err(Error::InvalidEscape(
1292                        "Expected 1-6 digits, got 0 digits in Unicode escape",
1293                    ));
1294                }
1295
1296                self.expect_char(
1297                    '}',
1298                    Error::InvalidEscape("No } at the end of Unicode escape"),
1299                )?;
1300                let c = char_from_u32(bytes).ok_or(Error::InvalidEscape(
1301                    "Not a valid Unicode-escaped character",
1302                ))?;
1303
1304                EscapeCharacter::Utf8(c)
1305            }
1306            _ => return Err(Error::InvalidEscape("Unknown escape character")),
1307        };
1308
1309        Ok(c)
1310    }
1311
1312    fn skip_comment(&mut self) -> Result<Option<Comment>> {
1313        if self.consume_char('/') {
1314            match self.next_char()? {
1315                '/' => {
1316                    let bytes = self.next_chars_while_len(|c| c != '\n');
1317
1318                    self.advance_bytes(bytes);
1319
1320                    if self.src().is_empty() {
1321                        Ok(Some(Comment::UnclosedLine))
1322                    } else {
1323                        Ok(Some(Comment::ClosedLine))
1324                    }
1325                }
1326                '*' => {
1327                    let mut level = 1;
1328
1329                    while level > 0 {
1330                        let bytes = self.next_chars_while_len(|c| !matches!(c, '/' | '*'));
1331
1332                        if self.src().is_empty() {
1333                            return Err(Error::UnclosedBlockComment);
1334                        }
1335
1336                        self.advance_bytes(bytes);
1337
1338                        // check whether / or * and take action
1339                        if self.consume_str("/*") {
1340                            level += 1;
1341                        } else if self.consume_str("*/") {
1342                            level -= 1;
1343                        } else {
1344                            self.next_char().map_err(|_| Error::UnclosedBlockComment)?;
1345                        }
1346                    }
1347
1348                    Ok(Some(Comment::Block))
1349                }
1350                c => Err(Error::UnexpectedChar(c)),
1351            }
1352        } else {
1353            Ok(None)
1354        }
1355    }
1356}
1357
1358enum Comment {
1359    ClosedLine,
1360    UnclosedLine,
1361    Block,
1362}
1363
1364pub trait Num {
1365    fn from_u8(x: u8) -> Self;
1366
1367    /// Returns `true` on overflow
1368    fn checked_mul_ext(&mut self, x: u8) -> bool;
1369
1370    /// Returns `true` on overflow
1371    fn checked_add_ext(&mut self, x: u8) -> bool;
1372
1373    /// Returns `true` on overflow
1374    fn checked_sub_ext(&mut self, x: u8) -> bool;
1375}
1376
1377macro_rules! impl_num {
1378    ($ty:ty) => {
1379        impl Num for $ty {
1380            fn from_u8(x: u8) -> Self {
1381                x as $ty
1382            }
1383
1384            fn checked_mul_ext(&mut self, x: u8) -> bool {
1385                match self.checked_mul(Self::from_u8(x)) {
1386                    Some(n) => {
1387                        *self = n;
1388                        false
1389                    }
1390                    None => true,
1391                }
1392            }
1393
1394            fn checked_add_ext(&mut self, x: u8) -> bool {
1395                match self.checked_add(Self::from_u8(x)) {
1396                    Some(n) => {
1397                        *self = n;
1398                        false
1399                    }
1400                    None => true,
1401                }
1402            }
1403
1404            fn checked_sub_ext(&mut self, x: u8) -> bool {
1405                match self.checked_sub(Self::from_u8(x)) {
1406                    Some(n) => {
1407                        *self = n;
1408                        false
1409                    }
1410                    None => true,
1411                }
1412            }
1413        }
1414    };
1415    ($($tys:ty)*) => {
1416        $( impl_num!($tys); )*
1417    };
1418}
1419
1420impl_num! { i8 i16 i32 i64 u8 u16 u32 u64 }
1421
1422#[cfg(feature = "integer128")]
1423impl_num! { i128 u128 }
1424
1425pub trait Integer: Sized {
1426    fn parse(parser: &mut Parser, sign: i8) -> Result<Self>;
1427
1428    fn try_from_parsed_integer(parsed: ParsedInteger, ron: &str) -> Result<Self>;
1429}
1430
1431macro_rules! impl_integer {
1432    ($wrap:ident($ty:ty)) => {
1433        impl Integer for $ty {
1434            fn parse(parser: &mut Parser, sign: i8) -> Result<Self> {
1435                parser.parse_integer(sign)
1436            }
1437
1438            fn try_from_parsed_integer(parsed: ParsedInteger, ron: &str) -> Result<Self> {
1439                match parsed {
1440                    ParsedInteger::$wrap(v) => Ok(v),
1441                    _ => Err(Error::InvalidValueForType {
1442                        expected: format!(
1443                            "a{} {}-bit {}signed integer",
1444                            if <$ty>::BITS == 8 { "n" } else { "n" },
1445                            <$ty>::BITS,
1446                            if <$ty>::MIN == 0 { "un" } else { "" },
1447                        ),
1448                        found: String::from(ron),
1449                    }),
1450                }
1451            }
1452        }
1453    };
1454    ($($wraps:ident($tys:ty))*) => {
1455        $( impl_integer!($wraps($tys)); )*
1456    };
1457}
1458
1459impl_integer! {
1460    I8(i8) I16(i16) I32(i32) I64(i64)
1461    U8(u8) U16(u16) U32(u32) U64(u64)
1462}
1463
1464#[cfg(feature = "integer128")]
1465impl_integer! { I128(i128) U128(u128) }
1466
1467pub enum ParsedInteger {
1468    I8(i8),
1469    I16(i16),
1470    I32(i32),
1471    I64(i64),
1472    #[cfg(feature = "integer128")]
1473    I128(i128),
1474    U8(u8),
1475    U16(u16),
1476    U32(u32),
1477    U64(u64),
1478    #[cfg(feature = "integer128")]
1479    U128(u128),
1480}
1481
1482impl Integer for ParsedInteger {
1483    fn parse(parser: &mut Parser, sign: i8) -> Result<Self> {
1484        if sign < 0 {
1485            let signed = parser.parse_integer::<LargeSInt>(-1)?;
1486
1487            return if let Ok(x) = i8::try_from(signed) {
1488                Ok(ParsedInteger::I8(x))
1489            } else if let Ok(x) = i16::try_from(signed) {
1490                Ok(ParsedInteger::I16(x))
1491            } else if let Ok(x) = i32::try_from(signed) {
1492                Ok(ParsedInteger::I32(x))
1493            } else {
1494                #[cfg(not(feature = "integer128"))]
1495                {
1496                    Ok(ParsedInteger::I64(signed))
1497                }
1498                #[cfg(feature = "integer128")]
1499                if let Ok(x) = i64::try_from(signed) {
1500                    Ok(ParsedInteger::I64(x))
1501                } else {
1502                    Ok(ParsedInteger::I128(signed))
1503                }
1504            };
1505        }
1506
1507        let unsigned = parser.parse_integer::<LargeUInt>(1)?;
1508
1509        if let Ok(x) = u8::try_from(unsigned) {
1510            Ok(ParsedInteger::U8(x))
1511        } else if let Ok(x) = u16::try_from(unsigned) {
1512            Ok(ParsedInteger::U16(x))
1513        } else if let Ok(x) = u32::try_from(unsigned) {
1514            Ok(ParsedInteger::U32(x))
1515        } else {
1516            #[cfg(not(feature = "integer128"))]
1517            {
1518                Ok(ParsedInteger::U64(unsigned))
1519            }
1520            #[cfg(feature = "integer128")]
1521            if let Ok(x) = u64::try_from(unsigned) {
1522                Ok(ParsedInteger::U64(x))
1523            } else {
1524                Ok(ParsedInteger::U128(unsigned))
1525            }
1526        }
1527    }
1528
1529    fn try_from_parsed_integer(parsed: ParsedInteger, _ron: &str) -> Result<Self> {
1530        Ok(parsed)
1531    }
1532}
1533
1534pub trait Float: Sized {
1535    fn parse(float: &str) -> Result<Self>;
1536
1537    fn try_from_parsed_float(parsed: ParsedFloat, ron: &str) -> Result<Self>;
1538}
1539
1540macro_rules! impl_float {
1541    ($wrap:ident($ty:ty: $bits:expr)) => {
1542        impl Float for $ty {
1543            fn parse(float: &str) -> Result<Self> {
1544                <$ty>::from_str(float).map_err(|_| Error::ExpectedFloat)
1545            }
1546
1547            fn try_from_parsed_float(parsed: ParsedFloat, ron: &str) -> Result<Self> {
1548                match parsed {
1549                    ParsedFloat::$wrap(v) => Ok(v),
1550                    _ => Err(Error::InvalidValueForType {
1551                        expected: format!(
1552                            "a {}-bit floating point number", $bits,
1553                        ),
1554                        found: String::from(ron),
1555                    }),
1556                }
1557            }
1558        }
1559    };
1560    ($($wraps:ident($tys:ty: $bits:expr))*) => {
1561        $( impl_float!($wraps($tys: $bits)); )*
1562    };
1563}
1564
1565impl_float! { F32(f32: 32) F64(f64: 64) }
1566
1567pub enum ParsedFloat {
1568    F32(f32),
1569    F64(f64),
1570}
1571
1572impl Float for ParsedFloat {
1573    fn parse(float: &str) -> Result<Self> {
1574        let value = f64::from_str(float).map_err(|_| Error::ExpectedFloat)?;
1575
1576        #[allow(clippy::cast_possible_truncation)]
1577        if value.total_cmp(&f64::from(value as f32)).is_eq() {
1578            Ok(ParsedFloat::F32(value as f32))
1579        } else {
1580            Ok(ParsedFloat::F64(value))
1581        }
1582    }
1583
1584    fn try_from_parsed_float(parsed: ParsedFloat, _ron: &str) -> Result<Self> {
1585        Ok(parsed)
1586    }
1587}
1588
1589pub enum StructType {
1590    AnyTuple,
1591    EmptyTuple,
1592    NewtypeTuple,
1593    NonNewtypeTuple,
1594    Named,
1595    Unit,
1596}
1597
1598#[derive(Copy, Clone)] // GRCOV_EXCL_LINE
1599pub enum NewtypeMode {
1600    NoParensMeanUnit,
1601    InsideNewtype,
1602}
1603
1604#[derive(Copy, Clone)] // GRCOV_EXCL_LINE
1605pub enum TupleMode {
1606    ImpreciseTupleOrNewtype,
1607    DifferentiateNewtype,
1608}
1609
1610pub enum ParsedStr<'a> {
1611    Allocated(String),
1612    Slice(&'a str),
1613}
1614
1615pub enum ParsedByteStr<'a> {
1616    Allocated(Vec<u8>),
1617    Slice(&'a [u8]),
1618}
1619
1620impl<'a> ParsedStr<'a> {
1621    pub fn try_from_bytes(bytes: ParsedByteStr<'a>) -> Result<Self, Utf8Error> {
1622        match bytes {
1623            ParsedByteStr::Allocated(byte_buf) => Ok(ParsedStr::Allocated(
1624                String::from_utf8(byte_buf).map_err(|e| e.utf8_error())?,
1625            )),
1626            ParsedByteStr::Slice(bytes) => Ok(ParsedStr::Slice(from_utf8(bytes)?)),
1627        }
1628    }
1629}
1630
1631impl<'a> ParsedByteStr<'a> {
1632    pub fn try_from_base64(str: &ParsedStr<'a>) -> Option<Self> {
1633        // Adapted from MIT licensed Jenin Sutradhar's base 64 decoder
1634        // https://github.com/JeninSutradhar/base64-Rust-Encoder-Decoder/blob/ee1fb08cbb78024ec8cf5e786815acb239169f02/src/lib.rs#L84-L128
1635        fn try_decode_base64(str: &str) -> Option<Vec<u8>> {
1636            const CHARSET: &[u8; 64] =
1637                b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1638            const PADDING: u8 = b'=';
1639
1640            // fast reject for missing padding
1641            if (str.len() % 4) != 0 {
1642                return None;
1643            }
1644
1645            let bstr_no_padding = str.trim_end_matches(char::from(PADDING)).as_bytes();
1646
1647            // fast reject for excessive padding
1648            if (str.len() - bstr_no_padding.len()) > 2 {
1649                return None;
1650            }
1651
1652            // fast reject for extraneous bytes after padding
1653            if bstr_no_padding.contains(&PADDING) {
1654                return None;
1655            }
1656
1657            // fast reject for non-ASCII
1658            if !str.is_ascii() {
1659                return None;
1660            }
1661
1662            let mut collected_bits = 0_u8;
1663            let mut byte_buffer = 0_u16;
1664            let mut bytes = bstr_no_padding.iter().copied();
1665            let mut binary = Vec::new();
1666
1667            'decodeloop: loop {
1668                while collected_bits < 8 {
1669                    if let Some(nextbyte) = bytes.next() {
1670                        #[allow(clippy::cast_possible_truncation)]
1671                        if let Some(idx) = CHARSET.iter().position(|&x| x == nextbyte) {
1672                            byte_buffer |= ((idx & 0b0011_1111) as u16) << (10 - collected_bits);
1673                            collected_bits += 6;
1674                        } else {
1675                            return None;
1676                        }
1677                    } else {
1678                        break 'decodeloop;
1679                    }
1680                }
1681
1682                binary.push(((0b1111_1111_0000_0000 & byte_buffer) >> 8) as u8);
1683                byte_buffer &= 0b0000_0000_1111_1111;
1684                byte_buffer <<= 8;
1685                collected_bits -= 8;
1686            }
1687
1688            if usize::from(collected_bits) != ((str.len() - bstr_no_padding.len()) * 2) {
1689                return None;
1690            }
1691
1692            Some(binary)
1693        }
1694
1695        let base64_str = match str {
1696            ParsedStr::Allocated(string) => string.as_str(),
1697            ParsedStr::Slice(str) => str,
1698        };
1699
1700        try_decode_base64(base64_str).map(ParsedByteStr::Allocated)
1701    }
1702}
1703
1704#[derive(Copy, Clone)] // GRCOV_EXCL_LINE
1705enum EscapeEncoding {
1706    Binary,
1707    Utf8,
1708}
1709
1710enum EscapeCharacter {
1711    Ascii(u8),
1712    Utf8(char),
1713}
1714
1715#[cfg(test)]
1716mod tests {
1717    use super::*;
1718
1719    #[test]
1720    fn decode_x10() {
1721        let mut bytes = Parser::new("10").unwrap();
1722        assert_eq!(bytes.decode_ascii_escape(), Ok(b'\x10'));
1723    }
1724
1725    #[test]
1726    fn track_prior_ws() {
1727        const SOURCE: &str = "   /*hey*/ 42       /*bye*/ 24  ";
1728        let mut bytes = Parser::new(SOURCE).unwrap();
1729
1730        assert_eq!(bytes.src(), "42       /*bye*/ 24  ");
1731        assert_eq!(bytes.pre_ws_src(), SOURCE);
1732
1733        bytes.skip_ws().unwrap();
1734
1735        assert_eq!(bytes.src(), "42       /*bye*/ 24  ");
1736        assert_eq!(bytes.pre_ws_src(), SOURCE);
1737
1738        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
1739
1740        assert_eq!(bytes.src(), "       /*bye*/ 24  ");
1741        assert_eq!(bytes.pre_ws_src(), SOURCE);
1742
1743        bytes.skip_ws().unwrap();
1744        bytes.skip_ws().unwrap();
1745
1746        assert_eq!(bytes.src(), "24  ");
1747        assert_eq!(bytes.pre_ws_src(), "       /*bye*/ 24  ");
1748
1749        let mut bytes = Parser::new("42").unwrap();
1750        bytes.skip_ws().unwrap();
1751        bytes.skip_ws().unwrap();
1752        assert_eq!(bytes.src(), "42");
1753        assert_eq!(bytes.pre_ws_src(), "42");
1754        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
1755        bytes.skip_ws().unwrap();
1756        bytes.skip_ws().unwrap();
1757        assert_eq!(bytes.src(), "");
1758        assert_eq!(bytes.pre_ws_src(), "");
1759
1760        let mut bytes = Parser::new("  42  ").unwrap();
1761        bytes.skip_ws().unwrap();
1762        bytes.skip_ws().unwrap();
1763        assert_eq!(bytes.src(), "42  ");
1764        assert_eq!(bytes.pre_ws_src(), "  42  ");
1765        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
1766        bytes.skip_ws().unwrap();
1767        bytes.skip_ws().unwrap();
1768        assert_eq!(bytes.src(), "");
1769        assert_eq!(bytes.pre_ws_src(), "  ");
1770
1771        let mut bytes = Parser::new("  42  //").unwrap();
1772        bytes.skip_ws().unwrap();
1773        bytes.skip_ws().unwrap();
1774        assert_eq!(bytes.src(), "42  //");
1775        assert_eq!(bytes.pre_ws_src(), "  42  //");
1776        assert_eq!(bytes.integer::<u8>().unwrap(), 42);
1777        bytes.skip_ws().unwrap();
1778        bytes.skip_ws().unwrap();
1779        assert_eq!(bytes.src(), "");
1780        assert_eq!(bytes.pre_ws_src(), "  //");
1781    }
1782
1783    #[test]
1784    fn parser_cursor_eq_cmp() {
1785        assert!(
1786            ParserCursor {
1787                cursor: 42,
1788                pre_ws_cursor: 42,
1789                last_ws_len: 42
1790            } == ParserCursor {
1791                cursor: 42,
1792                pre_ws_cursor: 24,
1793                last_ws_len: 24
1794            }
1795        );
1796        assert!(
1797            ParserCursor {
1798                cursor: 42,
1799                pre_ws_cursor: 42,
1800                last_ws_len: 42
1801            } != ParserCursor {
1802                cursor: 24,
1803                pre_ws_cursor: 42,
1804                last_ws_len: 42
1805            }
1806        );
1807
1808        assert!(
1809            ParserCursor {
1810                cursor: 42,
1811                pre_ws_cursor: 42,
1812                last_ws_len: 42
1813            } < ParserCursor {
1814                cursor: 43,
1815                pre_ws_cursor: 24,
1816                last_ws_len: 24
1817            }
1818        );
1819        assert!(
1820            ParserCursor {
1821                cursor: 42,
1822                pre_ws_cursor: 42,
1823                last_ws_len: 42
1824            } > ParserCursor {
1825                cursor: 41,
1826                pre_ws_cursor: 24,
1827                last_ws_len: 24
1828            }
1829        );
1830    }
1831
1832    #[test]
1833    fn empty_src_is_not_a_float() {
1834        assert!(!Parser::new("").unwrap().next_bytes_is_float());
1835    }
1836
1837    #[test]
1838    fn base64_deprecation_error() {
1839        let err = crate::from_str::<bytes::Bytes>("\"SGVsbG8gcm9uIQ==\"").unwrap_err();
1840
1841        assert_eq!(
1842            err,
1843            SpannedError {
1844                code: Error::InvalidValueForType {
1845                    expected: String::from("the Rusty byte string b\"Hello ron!\""),
1846                    found: String::from("the ambiguous base64 string \"SGVsbG8gcm9uIQ==\"")
1847                },
1848                span: Span {
1849                    start: Position { line: 1, col: 2 },
1850                    end: Position { line: 1, col: 19 },
1851                }
1852            }
1853        );
1854
1855        let err = crate::from_str::<bytes::Bytes>("r\"SGVsbG8gcm9uIQ==\"").unwrap_err();
1856
1857        assert_eq!(format!("{}", err.code), "Expected the Rusty byte string b\"Hello ron!\" but found the ambiguous base64 string \"SGVsbG8gcm9uIQ==\" instead");
1858
1859        assert_eq!(
1860            crate::from_str::<bytes::Bytes>("\"invalid=\"").unwrap_err(),
1861            SpannedError {
1862                code: Error::InvalidValueForType {
1863                    expected: String::from("the Rusty byte string b\"\\x8a{\\xda\\x96\\'\""),
1864                    found: String::from("the ambiguous base64 string \"invalid=\"")
1865                },
1866                span: Span {
1867                    start: Position { line: 1, col: 2 },
1868                    end: Position { line: 1, col: 11 },
1869                }
1870            }
1871        );
1872
1873        assert_eq!(
1874            crate::from_str::<bytes::Bytes>("r\"invalid=\"").unwrap_err(),
1875            SpannedError {
1876                code: Error::InvalidValueForType {
1877                    expected: String::from("the Rusty byte string b\"\\x8a{\\xda\\x96\\'\""),
1878                    found: String::from("the ambiguous base64 string \"invalid=\"")
1879                },
1880                span: Span {
1881                    start: Position { line: 1, col: 3 },
1882                    end: Position { line: 1, col: 12 },
1883                }
1884            }
1885        );
1886
1887        assert_eq!(
1888            crate::from_str::<bytes::Bytes>("r\"invalid\"").unwrap_err(),
1889            SpannedError {
1890                code: Error::ExpectedByteString,
1891                span: Span {
1892                    start: Position { line: 1, col: 3 },
1893                    end: Position { line: 1, col: 11 },
1894                }
1895            }
1896        );
1897    }
1898}