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 pub exts: Extensions,
60 src: &'a str,
61 cursor: ParserCursor,
62}
63
64#[derive(Copy, Clone)] pub 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
85impl<'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 {
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
219impl<'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 let byte = match self.next_char()? {
300 '\\' => match self.parse_escape(EscapeEncoding::Binary, true)? {
301 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 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 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 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 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 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 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 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 Some(':') => return Ok(StructType::Named),
576 Some(',') => {
578 parser.skip_next_char();
579 parser.skip_ws()?;
580 if parser.check_char(')') {
581 return Ok(StructType::NewtypeTuple);
583 }
584 return Ok(StructType::NonNewtypeTuple);
586 }
587 Some(')') => return Ok(StructType::NewtypeTuple),
589 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 while braces > 0 {
603 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 Err(err @ (Error::ExpectedStringEnd | Error::Eof)) => return Err(err),
614 Err(_) => parser.set_cursor(cursor_backup),
615 }
616 let cursor_backup = parser.cursor;
617 match parser.byte_string_no_base64() {
619 Ok(_) => (),
620 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 let backup_cursor = self.cursor;
646
647 let result = check_struct_type_inner(self, newtype, tuple);
648
649 if result.is_ok() {
650 self.set_cursor(backup_cursor);
652 }
653
654 result
655 }
656
657 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 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 !comma && self.check_ident_other_char(0) {
724 return Err(Error::ExpectedComma);
725 }
726
727 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 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\"") || self.check_str("b'") || self.check_str("br#") || self.check_str("br\"") || self.check_str("r\"") || self.check_str("r#\"") || self.check_str("r##") || false
854 {
855 return None;
856 }
857
858 if self.check_str("r#") {
859 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 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 #[allow(clippy::nonminimal_bool)]
899 if self.check_str("b\"") || self.check_str("b'") || self.check_str("br#") || self.check_str("br\"") || self.check_str("r\"") || self.check_str("r#\"") || self.check_str("r##") || 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 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 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 #[allow(deprecated)]
1034 base64_result.map_err(Error::Base64Error)
1035 } else {
1036 match base64_result {
1037 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 #[allow(deprecated)]
1049 base64_result.map_err(Error::Base64Error)
1050 } else {
1051 match base64_result {
1052 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 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 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 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 break Ok((ParsedByteStr::Allocated(s), new_str_end + 1));
1161 }
1162 }
1163 } else {
1164 let s = &self.src().as_bytes()[..str_end];
1165
1166 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 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 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 let b: u8 = self.decode_ascii_escape()?;
1227 if let EscapeEncoding::Binary = encoding {
1228 return Ok(EscapeCharacter::Ascii(b));
1229 }
1230
1231 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 return Err(Error::InvalidEscape(
1241 "Not a valid byte-escaped Unicode character",
1242 ));
1243 }
1244
1245 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 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 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 fn checked_mul_ext(&mut self, x: u8) -> bool;
1366
1367 fn checked_add_ext(&mut self, x: u8) -> bool;
1369
1370 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)] pub enum NewtypeMode {
1597 NoParensMeanUnit,
1598 InsideNewtype,
1599}
1600
1601#[derive(Copy, Clone)] pub 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)] enum 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}