ron/
parse.rs

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