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