1#[cfg(feature = "num")]
4use crate::lexical::{NumError, parse_f64_result, parse_int_err};
5use crate::{
6 Pos,
7 lexical::{
8 self, state, {Analyzer, ErrorKind, Token, Unescaped},
9 },
10 syntax,
11};
12use alloc::{string::String, sync::Arc, vec::Vec};
13#[cfg(feature = "num")]
14use core::str::FromStr;
15use core::{
16 cmp::Ordering,
17 fmt,
18 ops::{Deref, Range},
19};
20
21#[derive(Clone, Debug)]
22struct Ref<B> {
23 buf: Arc<B>,
24 rng: Range<usize>,
25}
26
27impl<B: Deref<Target = [u8]>> Ref<B> {
28 fn new(buf: Arc<B>, rng: Range<usize>) -> Ref<B> {
29 Self { buf, rng }
30 }
31
32 fn as_str(&self) -> &str {
33 unsafe { core::str::from_utf8_unchecked(&self.buf[self.rng.start..self.rng.end]) }
34 }
35}
36
37const INLINE_LEN: usize = 30;
38
39type InlineBuf = [u8; INLINE_LEN];
40
41#[derive(Clone, Debug)]
42enum InnerContent<B: Deref<Target = [u8]>> {
43 Static(&'static str),
44 Inline(u8, InlineBuf),
45 NotEscaped(Ref<B>),
46 Escaped(Ref<B>),
47}
48
49#[derive(Clone, Debug)]
54pub struct Content<B: Deref<Target = [u8]> + fmt::Debug>(InnerContent<B>);
55
56impl Content<Vec<u8>> {
57 pub fn from_static(s: &'static str) -> Self {
83 let b = s.as_bytes();
84 match state::Machine::verify_static(b) {
85 false => Self(InnerContent::Static(s)),
86 true => Self(InnerContent::Escaped(Ref::new(
87 Arc::new(b.to_vec()),
88 0..b.len(),
89 ))),
90 }
91 }
92}
93
94impl<B: Deref<Target = [u8]> + fmt::Debug> Content<B> {
95 #[inline]
101 pub fn literal(&self) -> &str {
102 match &self.0 {
103 InnerContent::Static(s) => s,
104 InnerContent::Inline(len, buf) => Self::inline_str(*len, buf),
105 InnerContent::NotEscaped(r) | InnerContent::Escaped(r) => r.as_str(),
106 }
107 }
108
109 #[inline]
113 pub fn literal_len(&self) -> usize {
114 match &self.0 {
115 InnerContent::Static(s) => s.len(),
116 InnerContent::Inline(len, _) => *len as usize,
117 InnerContent::NotEscaped(r) | InnerContent::Escaped(r) => r.rng.end - r.rng.start,
118 }
119 }
120
121 #[inline(always)]
127 pub fn is_escaped(&self) -> bool {
128 matches!(self.0, InnerContent::Escaped(_))
129 }
130
131 pub fn unescaped(&self) -> Unescaped<&str> {
149 match &self.0 {
150 InnerContent::Static(s) => Unescaped::Literal(s),
151 InnerContent::Inline(len, buf) => Unescaped::Literal(Self::inline_str(*len, buf)),
152 InnerContent::NotEscaped(r) => Unescaped::Literal(r.as_str()),
153 InnerContent::Escaped(r) => {
154 let mut buf = Vec::new();
155 lexical::unescape(r.as_str(), &mut buf);
156
157 let s = unsafe { String::from_utf8_unchecked(buf) };
160
161 Unescaped::Expanded(s)
162 }
163 }
164 }
165
166 pub fn unescaped_cmp(&self, other: &str) -> Ordering {
205 let mut a = self.literal().as_bytes();
206 let mut b = other.as_bytes();
207 loop {
208 match a.iter().position(|&b| b == b'\\') {
209 None => return a.cmp(b),
210 Some(i) => {
211 let o = a[..i].cmp(&b[..i.min(b.len())]);
212 if o != Ordering::Equal {
213 return o;
214 } else if i >= b.len() {
215 return Ordering::Greater;
216 }
217 let y = b[i];
218 match lexical::unescape_byte(a[i + 1]) {
219 lexical::UnescapeByte::Byte(x) if x != y => return x.cmp(&y),
220 lexical::UnescapeByte::Byte(_) => {
221 a = &a[i + 2..];
222 b = &b[i + 1..];
223 }
224 lexical::UnescapeByte::Unicode => {
225 a = &a[i + 2..];
226 let (x, n) = lexical::unescape_unicode(&mut a);
227 let n = n as usize;
228 let o = x[..n].cmp(&b[i..i + n.min(b.len() - i)]);
229 if o != Ordering::Equal {
230 return o;
231 }
232 b = &b[i + n..];
233 }
234 }
235 }
236 }
237 }
238 }
239
240 #[cfg(feature = "num")]
264 #[inline]
265 pub fn parse_i64(&self) -> Result<i64, NumError> {
266 let chunk = self.literal().as_bytes();
267
268 parse_int!(one_slice, chunk, i64, 1, i64::MIN)
269 }
270
271 #[cfg(feature = "num")]
295 #[inline]
296 pub fn parse_u64(&self) -> Result<u64, NumError> {
297 let chunk = self.literal().as_bytes();
298
299 parse_int!(one_slice, chunk, u64, 0, u64::MAX)
300 }
301
302 #[cfg(feature = "num_ext")]
330 #[inline]
331 pub fn parse_i128(&self) -> Result<i128, NumError> {
332 let chunk = self.literal().as_bytes();
333
334 parse_int!(one_slice, chunk, i128, 1, i128::MIN)
335 }
336
337 #[cfg(feature = "num")]
363 #[inline]
364 pub fn parse_f64(&self) -> Result<f64, NumError> {
365 parse_f64_result(f64::from_str(self.literal()))
366 }
367}
368
369impl<B: Deref<Target = [u8]> + fmt::Debug> Content<B> {
370 fn from_buf(buf: &Arc<B>, r: Range<usize>, escaped: bool) -> Self {
371 debug_assert!(r.start <= r.end);
372 debug_assert!(r.end <= buf.len());
373
374 let len = r.end - r.start;
375
376 if len <= INLINE_LEN && !escaped {
377 let mut inner: InlineBuf = [0; INLINE_LEN];
378 inner[..len].copy_from_slice(&buf[r]);
379
380 Self(InnerContent::Inline(len as u8, inner))
381 } else {
382 let r = Ref::new(Arc::clone(buf), r);
383
384 Self(if !escaped {
385 InnerContent::NotEscaped(r)
386 } else {
387 InnerContent::Escaped(r)
388 })
389 }
390 }
391
392 fn inline_str(len: u8, buf: &InlineBuf) -> &str {
393 unsafe { core::str::from_utf8_unchecked(&buf[0..len as usize]) }
394 }
395}
396
397impl Default for Content<Vec<u8>> {
398 fn default() -> Self {
399 Self(InnerContent::Static("")) }
401}
402
403impl<B: Deref<Target = [u8]> + fmt::Debug> fmt::Display for Content<B> {
404 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
405 f.write_str(self.literal())
406 }
407}
408
409impl<B: Deref<Target = [u8]> + fmt::Debug> super::Content for Content<B> {
410 type Literal<'a>
411 = &'a str
412 where
413 Self: 'a;
414
415 #[inline(always)]
416 fn literal<'a>(&'a self) -> Self::Literal<'a> {
417 Content::literal(self)
418 }
419
420 #[inline(always)]
421 fn literal_len(&self) -> usize {
422 Content::literal_len(self)
423 }
424
425 #[inline(always)]
426 fn is_escaped(&self) -> bool {
427 Content::is_escaped(self)
428 }
429
430 #[inline(always)]
431 fn unescaped<'a>(&'a self) -> Unescaped<Self::Literal<'a>> {
432 Content::unescaped(self)
433 }
434
435 #[inline(always)]
436 fn unescaped_cmp(&self, other: &str) -> Ordering {
437 Content::unescaped_cmp(self, other)
438 }
439
440 #[cfg(feature = "num")]
441 #[inline(always)]
442 fn parse_i64(&self) -> Result<i64, NumError> {
443 Content::parse_i64(self)
444 }
445
446 #[cfg(feature = "num")]
447 #[inline(always)]
448 fn parse_u64(&self) -> Result<u64, NumError> {
449 Content::parse_u64(self)
450 }
451
452 #[cfg(feature = "num_ext")]
453 #[inline(always)]
454 fn parse_i128(&self) -> Result<i128, NumError> {
455 Content::parse_i128(self)
456 }
457
458 #[cfg(feature = "num")]
459 #[inline(always)]
460 fn parse_f64(&self) -> Result<f64, NumError> {
461 Content::parse_f64(self)
462 }
463}
464
465#[cfg(target_pointer_width = "64")]
467const _: [(); 32] = [(); core::mem::size_of::<Content<Vec<u8>>>()];
468
469#[derive(Copy, Clone, Debug)]
473pub struct Error {
474 kind: ErrorKind,
475 pos: Pos,
476}
477
478impl Error {
479 #[inline(always)]
484 pub fn kind(&self) -> ErrorKind {
485 self.kind
486 }
487
488 #[inline(always)]
493 pub fn pos(&self) -> &Pos {
494 &self.pos
495 }
496}
497
498impl fmt::Display for Error {
499 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
500 self.kind.fmt_at(f, Some(&self.pos))
501 }
502}
503
504impl core::error::Error for Error {}
505
506impl lexical::Error for Error {
507 #[inline(always)]
508 fn kind(&self) -> ErrorKind {
509 Error::kind(self)
510 }
511
512 #[inline(always)]
513 fn pos(&self) -> &Pos {
514 Error::pos(self)
515 }
516}
517
518#[derive(Copy, Clone, Debug)]
519struct StoredContent {
520 len: usize,
521 escaped: bool,
522}
523
524impl StoredContent {
525 #[inline(always)]
526 fn new(len: usize, escaped: bool) -> Self {
527 Self { len, escaped }
528 }
529}
530
531impl Default for StoredContent {
532 fn default() -> Self {
533 Self::new(0, false)
534 }
535}
536
537pub struct FixedAnalyzer<B: Deref<Target = [u8]> + fmt::Debug> {
607 buf: Arc<B>,
608 content: StoredContent,
609 err: Option<Error>,
610 mach: state::Machine<state::DerefBuf<B, Arc<B>>>,
611 pos: Pos,
612}
613
614impl<B: Deref<Target = [u8]> + fmt::Debug> Clone for FixedAnalyzer<B> {
615 fn clone(&self) -> Self {
616 Self {
617 buf: Arc::clone(&self.buf),
618 content: self.content,
619 err: self.err,
620 mach: self.mach.clone(),
621 pos: self.pos,
622 }
623 }
624}
625
626impl<B: Deref<Target = [u8]> + fmt::Debug> FixedAnalyzer<B> {
627 pub fn new(buf: B) -> Self {
641 let buf = Arc::new(buf);
642 let mach = state::Machine::new(state::DerefBuf::new(Arc::clone(&buf)));
643 let content = StoredContent::default();
644 let err = None;
645 let pos = Pos::default();
646
647 Self {
648 buf,
649 content,
650 err,
651 pos,
652 mach,
653 }
654 }
655
656 #[allow(clippy::should_implement_trait)]
671 pub fn next(&mut self) -> Token {
672 if self.err.is_some() {
673 return Token::Err;
674 }
675
676 self.pos = *self.mach.pos();
677
678 match self.mach.next() {
679 state::Next::Done(token, escaped, n) => {
680 self.content = StoredContent::new(n, escaped);
681
682 token
683 }
684 state::Next::Part(token, n) => match self.mach.end() {
685 state::End::Done => {
686 self.content = StoredContent::new(n, false);
687
688 token
689 }
690 state::End::Nil => unreachable!(),
691 state::End::Err => {
692 let kind = self.mach.err_kind().expect("there should be an error kind");
693 let pos = *self.mach.pos();
694 self.err = Some(Error { kind, pos });
695
696 Token::Err
697 }
698 },
699 state::Next::Nil => {
700 self.content = StoredContent::default();
701
702 Token::Eof
703 }
704 state::Next::Err(_) => {
705 let kind = self.mach.err_kind().expect("there should be an error kind");
706 let pos = *self.mach.pos();
707 self.err = Some(Error { kind, pos });
708
709 Token::Err
710 }
711 }
712 }
713
714 #[inline]
741 pub fn content(&self) -> Content<B> {
742 if let Ok(content) = self.try_content() {
743 content
744 } else {
745 panic!("no content: last `next()` returned `Token::Err` (use `err()` instead)");
746 }
747 }
748
749 #[inline]
776 pub fn err(&self) -> Error {
777 if let Err(err) = self.try_content() {
778 err
779 } else {
780 panic!("no error: last `next()` did not return `Token::Err` (use `content()` instead)");
781 }
782 }
783
784 #[inline(always)]
833 pub fn pos(&self) -> &Pos {
834 &self.pos
835 }
836
837 pub fn try_content(&self) -> Result<Content<B>, Error> {
865 match self.err {
866 None => {
867 let offset = self.pos.offset;
868
869 Ok(Content::from_buf(
870 &self.buf,
871 offset..offset + self.content.len,
872 self.content.escaped,
873 ))
874 }
875 Some(err) => Err(err),
876 }
877 }
878
879 pub fn into_parser(self) -> syntax::Parser<FixedAnalyzer<B>> {
902 syntax::Parser::new(self)
903 }
904}
905
906impl<B: Deref<Target = [u8]> + fmt::Debug> Analyzer for FixedAnalyzer<B> {
907 type Content = Content<B>;
908 type Error = Error;
909
910 #[inline(always)]
911 fn next(&mut self) -> Token {
912 FixedAnalyzer::next(self)
913 }
914
915 #[inline(always)]
916 fn try_content(&self) -> Result<Self::Content, Error> {
917 FixedAnalyzer::try_content(self)
918 }
919
920 #[inline(always)]
921 fn pos(&self) -> &Pos {
922 FixedAnalyzer::pos(self)
923 }
924}
925
926#[cfg(test)]
927mod tests {
928 use super::*;
929 use crate::lexical::Expect;
930 use rstest::rstest;
931 use std::error::Error as _;
932
933 #[rstest]
934 #[case::invalid_char("a")]
935 #[case::f("f")]
936 #[case::fa("fa")]
937 #[case::fal("fal")]
938 #[case::fals("fals")]
939 #[case::false_leading_space(" false")]
940 #[case::false_trailing_space("false ")]
941 #[case::n("n")]
942 #[case::nu("nu")]
943 #[case::nul("nul")]
944 #[case::null_leading_space(" null")]
945 #[case::null_trailing_space("null ")]
946 #[case::t("t")]
947 #[case::tr("tr")]
948 #[case::tru("tru")]
949 #[case::true_leading_space(" true")]
950 #[case::true_trailing_space("true ")]
951 #[case::num_dot(".")]
952 #[case::num_zero_dot("0.")]
953 #[case::num_zero_zero("00")]
954 #[case::num_leading_space(" 0")]
955 #[case::num_trailing_space("0 ")]
956 #[case::str_unterminated_0(r#"""#)]
957 #[case::str_unterminated_1(r#""a"#)]
958 #[case::str_leading_space(r#" "a""#)]
959 #[case::str_trailing_space(r#""a" "#)]
960 #[should_panic(expected = "invalid JSON content")]
961 fn test_content_from_static_panic(#[case] s: &'static str) {
962 let c = Content::from_static(s);
963
964 panic!("content unexpectedly created: {c:?}");
965 }
966
967 #[rstest]
968 #[case::eof("", None)]
969 #[case::arr_begin("[", None)]
970 #[case::arr_end("]", None)]
971 #[case::obj_begin("{", None)]
972 #[case::obj_end("}", None)]
973 #[case::value_sep(",", None)]
974 #[case::name_sep(":", None)]
975 #[case::white_space(" ", None)]
976 #[case::white_tab("\t", None)]
977 #[case::white_lf("\n", None)]
978 #[case::white_cr("\r", None)]
979 #[case::white_lots(" \t\t \r \r\n \t\n", None)]
980 #[case::lit_false("false", None)]
981 #[case::lit_null("null", None)]
982 #[case::lit_true("true", None)]
983 #[case::num_zero("0", None)]
984 #[case::num_zero_point_one("0.1", None)]
985 #[case::num_123("123", None)]
986 #[case::num_neg_zero("-0", None)]
987 #[case::num_neg_zero_point_one("-0.1", None)]
988 #[case::num_neg_123("-123", None)]
989 #[case::num_1e1("1e1", None)]
990 #[case::num_1e_plus_1("1e+1", None)]
991 #[case::num_1e_minus_1("1e-1", None)]
992 #[case::str_empty(r#""""#, None)]
993 #[case::str_a(r#""a""#, None)]
994 #[case::str_emoji(r#""🤠""#, None)]
995 #[case::str_escaped_nul(r#""\u0000""#, Some("\"\u{00}\""))]
996 fn test_content_from_static_ok(
997 #[case] s: &'static str,
998 #[case] unescaped: Option<&'static str>,
999 ) {
1000 let c = Content::from_static(s);
1001
1002 assert_eq!(s, c.literal());
1003 assert_eq!(s, c.to_string());
1004 assert_eq!(s.len(), c.literal_len());
1005 assert_eq!(s.len(), lexical::Content::literal_len(&c));
1006
1007 match unescaped {
1008 Some(u) => assert_eq!(u, c.unescaped()),
1009 None => assert!(!c.is_escaped()),
1010 };
1011 }
1012
1013 #[rstest]
1014 #[case::static_a(Content(InnerContent::Static("a")), "a", "a")]
1015 #[case::inline_empty(Content(inline_buf(b"").into()), "", "")]
1016 #[case::inline_a_1(Content(inline_buf(b"a").into()), "a", "a")]
1017 #[case::inline_a_inline_len(Content(inline_buf(&[b'a'; INLINE_LEN]).into()), "a".repeat(INLINE_LEN), "a".repeat(INLINE_LEN))]
1018 #[case::not_escaped_empty(Content(InnerContent::NotEscaped(Ref::new(Arc::new(b"".to_vec()), 0..0))), "", "")]
1019 #[case::not_escaped_a(Content(InnerContent::NotEscaped(Ref::new(Arc::new(b"a".to_vec()), 0..1))), "a", "a")]
1020 #[case::escaped_empty(Content(InnerContent::Escaped(Ref::new(Arc::new(b"".to_vec()), 0..0))), "", "")]
1021 #[case::escaped_a(Content(InnerContent::Escaped(Ref::new(Arc::new(b"a".to_vec()), 0..1))), "a", "a")]
1022 #[case::escaped_nl(Content(InnerContent::Escaped(Ref::new(Arc::new(b"\\n".to_vec()), 0..2))), "\\n", "\n")]
1023 #[case::escaped_nul(Content(InnerContent::Escaped(Ref::new(Arc::new(b"\\u0000".to_vec()), 0..6))), "\\u0000", "\u{0000}")]
1024 fn test_content(
1025 #[case] content: Content<Vec<u8>>,
1026 #[case] literal: impl AsRef<str>,
1027 #[case] unescaped: impl AsRef<str>,
1028 ) {
1029 let literal = literal.as_ref();
1030 let unescaped = unescaped.as_ref();
1031
1032 assert_eq!(literal, content.literal());
1033 assert_eq!(literal, content.to_string());
1034 assert_eq!(literal.len(), content.literal_len());
1035 assert_eq!(literal.len(), lexical::Content::literal_len(&content));
1036 assert_eq!(unescaped, content.unescaped());
1037 assert_eq!(unescaped, lexical::Content::unescaped(&content));
1038 assert_eq!(Ordering::Equal, content.unescaped_cmp(unescaped));
1039 }
1040
1041 #[rstest]
1042 #[case::arr_begin("[")]
1043 #[case::arr_end("]")]
1044 #[case::empty("")]
1045 #[case::lit_false("false")]
1046 #[case::lit_false("null")]
1047 #[case::lit_false("true")]
1048 #[case::name_sep(":")]
1049 #[case::num_0("1")]
1050 #[case::num_1("1")]
1051 #[case::num_pi("3.14159")]
1052 #[case::num_minus_1("-1")]
1053 #[case::num_big1("1234567890.1234567890")]
1054 #[case::num_big2("1e100")]
1055 #[case::num_big3("10.000e+99")]
1056 #[case::str_empty(r#""""#)]
1057 #[case::str_a(r#""a""#)]
1058 #[case::str_utf8_2_bytes(r#""è""#)]
1059 #[case::str_utf8_3_bytes(r#""€""#)]
1060 #[case::str_utf8_4_bytes(r#""🇮🇹""#)]
1061 #[case::str_utf8_all(r#""🇮🇹 Questo caffè costa 3€. ☕""#)]
1062 #[case::obj_begin("{")]
1063 #[case::obj_end("}")]
1064 #[case::value_sep(",")]
1065 #[case::white1(" ")]
1066 #[case::white2("\t")]
1067 #[case::white3("\r")]
1068 #[case::white4("\n")]
1069 #[case::white5(" \t\r\n \n\t\t\r \r\n\r")]
1070 fn test_content_unescaped_cmp_identity(#[case] input: &'static str) {
1071 let content = Content::from_static(input);
1072
1073 assert_eq!(
1074 Ordering::Equal,
1075 lexical::unescaped_cmp(content.literal(), input)
1076 );
1077 assert_eq!(Ordering::Equal, content.unescaped_cmp(input));
1078 assert_eq!(
1079 Ordering::Equal,
1080 lexical::Content::unescaped_cmp(&content, input)
1081 );
1082 }
1083
1084 #[rstest]
1085 #[case::empty_str_empty("", r#""""#, Ordering::Less)]
1086 #[case::empty_num("", "1", Ordering::Less)]
1087 #[case::empty_white("", " ", Ordering::Less)]
1088 #[case::num_empty("0", "", Ordering::Greater)]
1089 #[case::str_a_str_b(r#""a""#, r#""b""#, Ordering::Less)]
1090 #[case::str_a_str_empty(r#""a""#, r#""""#, Ordering::Greater)]
1091 #[case::str_b_str_a(r#""b""#, r#""a""#, Ordering::Greater)]
1092 #[case::str_bar_str_bard(r#""bar""#, r#""bard""#, Ordering::Less)]
1093 #[case::str_bar_str_bark(r#""bar""#, r#""bark""#, Ordering::Less)]
1094 #[case::str_bard_str_bar(r#""bard""#, r#""bar""#, Ordering::Greater)]
1095 #[case::str_bard_str_bark(r#""bard""#, r#""bark""#, Ordering::Less)]
1096 #[case::str_bark_str_bar(r#""bark""#, r#""bar""#, Ordering::Greater)]
1097 #[case::str_bark_str_bard(r#""bark""#, r#""bard""#, Ordering::Greater)]
1098 #[case::str_empty_empty(r#""""#, "", Ordering::Greater)]
1099 #[case::str_empty_str_a(r#""""#, r#""a""#, Ordering::Less)]
1100 #[case::str_esc_quot_str_quot(r#""\"""#, "\"\"\"", Ordering::Equal)]
1101 #[case::str_esc_bsol_str_bsol(r#""\\""#, "\"\\\"", Ordering::Equal)]
1102 #[case::str_esc_sol_str_sol(r#""\/""#, "\"/\"", Ordering::Equal)]
1103 #[case::str_esc_bs_str_bs(r#""\b""#, "\"\x08\"", Ordering::Equal)]
1104 #[case::str_esc_ff_str_ff(r#""\f""#, "\"\x0c\"", Ordering::Equal)]
1105 #[case::str_esc_nl_str_nl(r#""\n""#, "\"\n\"", Ordering::Equal)]
1106 #[case::str_esc_nl_str_cr(r#""\n""#, "\"\r\"", Ordering::Less)]
1107 #[case::str_esc_cr_str_cr(r#""\r""#, "\"\r\"", Ordering::Equal)]
1108 #[case::str_esc_cr_str_nl(r#""\r""#, "\"\n\"", Ordering::Greater)]
1109 #[case::str_esc_tab_str_tab(r#""\t""#, "\"\t\"", Ordering::Equal)]
1110 #[case::str_esc_u_0008_str_bs(r#""\u0008""#, "\"\x08\"", Ordering::Equal)]
1111 #[case::str_esc_u_0009_str_tab(r#""\u0009""#, "\"\t\"", Ordering::Equal)]
1112 #[case::str_esc_u_000a_str_nl(r#""\u000a""#, "\"\n\"", Ordering::Equal)]
1113 #[case::str_esc_u_000c_str_ff(r#""\u000c""#, "\"\x0c\"", Ordering::Equal)]
1114 #[case::str_esc_u_000d_str_cr(r#""\u000d""#, "\"\r\"", Ordering::Equal)]
1115 #[case::str_esc_u_0022_str_quot(r#""\u0022""#, "\"\"\"", Ordering::Equal)]
1116 #[case::str_esc_u_002f_str_sol(r#""\u002f""#, "\"/\"", Ordering::Equal)]
1117 #[case::str_esc_u_005c_str_bsol(r#""\u005c""#, "\"\\\"", Ordering::Equal)]
1118 #[case::str_esc_u_0062_str_a(r#""\u0063""#, r#""a""#, Ordering::Greater)]
1119 #[case::str_esc_u_00e8_str_e_grave(r#""\u00e8""#, "\"\u{00e8}\"", Ordering::Equal)]
1120 #[case::str_esc_u_20ac_str_euro(r#""\u20ac""#, "\"\u{20ac}\"", Ordering::Equal)]
1121 #[case::str_esc_u_surrogate_str_globe(r#""\ud83c\udf0d""#, "\"\u{1f30d}\"", Ordering::Equal)]
1122 #[case::str_esc_at_end_of_longer_str(r#""abcde\n""#, r#""abc""#, Ordering::Greater)]
1123 #[case::str_esc_consecutive(r#""\n\t""#, "\"\n\t\"", Ordering::Equal)]
1124 #[case::str_where_other_terminates_early(r#""\n""#, "\"", Ordering::Greater)]
1125 #[case::white_empty(" ", "", Ordering::Greater)]
1126 #[case::smoke_1(
1127 r#""Path: C:\\Users\\alice\/docs""#,
1128 "\"Path: C:\\Users\\alice/docs\"",
1129 Ordering::Equal
1130 )]
1131 #[case::smoke_2(
1132 r#""At the caff\u00e8 counter, he paid the 10,50\u00a0\u20ac and\nquickly downed the cappucino. Then,\r\n\twith a quick\"ciao\u0022, he turned and walked out.""#,
1133 "\"At the caffè counter, he paid the 10,50\u{00a0}€ and\nquickly downed the cappucino. Then,\r\n\twith a quick\"ciao\", he turned and walked out.\"",
1134 Ordering::Equal,
1135 )]
1136 #[case::smoke_3(
1137 r#""At the caff\u00e8 counter, he paid the 10,50\u00a0\u20ac and\nquickly downed the cappucino. Then,\r\n\twith a quick\"ciao\u0022, he turned and ran out.""#,
1138 "\"At the caffè counter, he paid the 10,50\u{00a0}€ and\nquickly downed the cappucino. Then,\r\n\twith a quick\"ciao\", he turned and walked out.\"",
1139 Ordering::Less,
1140 )]
1141 fn test_unescaped_cmp_ok(#[case] a: &'static str, #[case] b: &str, #[case] expect: Ordering) {
1142 let content = Content::from_static(a);
1143
1144 assert_eq!(expect, lexical::unescaped_cmp(content.literal(), b));
1145 assert_eq!(expect, content.unescaped_cmp(b));
1146 assert_eq!(expect, lexical::Content::unescaped_cmp(&content, b));
1147 }
1148
1149 #[cfg(feature = "num")]
1150 #[rstest]
1151 #[case::zero("0", 0)]
1152 #[case::minus_zero("-0", 0)]
1153 #[case::one("1", 1)]
1154 #[case::minus_one("-1", -1)]
1155 #[case::forty_two("42", 42)]
1156 #[case::minus_forty_two("-42", -42)]
1157 #[case::all_digits("9876543210", 9876543210)]
1158 #[case::max_minus_1(format!("{}", i64::MAX-1), i64::MAX-1)]
1159 #[case::max(format!("{}", i64::MAX), i64::MAX)]
1160 #[case::min_plus_1(format!("{}", i64::MIN+1), i64::MIN+1)]
1161 #[case::min(format!("{}", i64::MIN), i64::MIN)]
1162 fn test_content_parse_i64_ok(#[case] input: impl AsRef<str>, #[case] expect: i64) {
1163 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1164 assert_eq!(Token::Num, an.next());
1165 let content = an.content();
1166 assert_eq!(Ok(expect), content.parse_i64());
1167 assert_eq!(Ok(expect), lexical::Content::parse_i64(&content));
1168 }
1169
1170 #[cfg(feature = "num")]
1171 #[rstest]
1172 #[case::decimal_zero("10.0", NumError::Format)]
1173 #[case::decimal("3.14159", NumError::Format)]
1174 #[case::exponent_zero("0e0", NumError::Format)]
1175 #[case::exponent_positive("10E+1", NumError::Format)]
1176 #[case::exponent_negative("1E-98", NumError::Format)]
1177 #[case::range_i64_min_minus_1(format!("{}", i64::MIN as i128 - 1), NumError::Range)]
1178 #[case::range_i128_min(format!("{}", i128::MIN), NumError::Range)]
1179 #[case::range_i64_max_plus_1(format!("{}", i64::MAX as i128 + 1), NumError::Range)]
1180 #[case::range_i128_max(format!("{}", i128::MAX), NumError::Range)]
1181 fn test_content_parse_i64_err(#[case] input: impl AsRef<str>, #[case] expect: NumError) {
1182 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1183 assert_eq!(Token::Num, an.next());
1184 let content = an.content();
1185 assert_eq!(Err(expect), content.parse_i64());
1186 assert_eq!(Err(expect), lexical::Content::parse_i64(&content));
1187 }
1188
1189 #[cfg(feature = "num")]
1190 #[rstest]
1191 #[case::zero("0", 0)]
1192 #[case::one("1", 1)]
1193 #[case::forty_two("42", 42)]
1194 #[case::all_digits("9876543210", 9876543210)]
1195 #[case::max_minus_1(format!("{}", u64::MAX-1), u64::MAX-1)]
1196 #[case::max(format!("{}", u64::MAX), u64::MAX)]
1197 fn test_content_parse_u64_ok(#[case] input: impl AsRef<str>, #[case] expect: u64) {
1198 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1199 assert_eq!(Token::Num, an.next());
1200 let content = an.content();
1201 assert_eq!(Ok(expect), content.parse_u64());
1202 assert_eq!(Ok(expect), lexical::Content::parse_u64(&content));
1203 }
1204
1205 #[cfg(feature = "num")]
1206 #[rstest]
1207 #[case::minus_zero("-0", NumError::Format)]
1208 #[case::minus_one("-1", NumError::Format)]
1209 #[case::minus_forty_two("-42", NumError::Format)]
1210 #[case::decimal_zero("10.0", NumError::Format)]
1211 #[case::decimal("3.14159", NumError::Format)]
1212 #[case::exponent_zero("0e0", NumError::Format)]
1213 #[case::exponent_positive("10E+1", NumError::Format)]
1214 #[case::exponent_negative("1E-98", NumError::Format)]
1215 #[case::range_u64_max_plus_1(format!("{}", u64::MAX as i128 + 1), NumError::Range)]
1216 #[case::range_i128_max(format!("{}", i128::MAX), NumError::Range)]
1217 fn test_content_parse_u64_err(#[case] input: impl AsRef<str>, #[case] expect: NumError) {
1218 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1219 assert_eq!(Token::Num, an.next());
1220 let content = an.content();
1221 assert_eq!(Err(expect), content.parse_u64());
1222 assert_eq!(Err(expect), lexical::Content::parse_u64(&content));
1223 }
1224
1225 #[cfg(feature = "num_ext")]
1226 #[rstest]
1227 #[case::zero("0", 0)]
1228 #[case::minus_zero("-0", 0)]
1229 #[case::one("1", 1)]
1230 #[case::minus_one("-1", -1)]
1231 #[case::forty_two("42", 42)]
1232 #[case::minus_forty_two("-42", -42)]
1233 #[case::all_digits("9876543210", 9876543210)]
1234 #[case::i64_max(format!("{}", i64::MAX), i64::MAX as i128)]
1235 #[case::i64_min(format!("{}", i64::MIN), i64::MIN as i128)]
1236 #[case::beyond_i64_max(format!("{}", i64::MAX as i128 + 1), i64::MAX as i128 + 1)]
1237 #[case::beyond_i64_min(format!("{}", i64::MIN as i128 - 1), i64::MIN as i128 - 1)]
1238 #[case::pow10_38(format!("{}", 10_i128.pow(38)), 10_i128.pow(38))]
1239 #[case::neg_pow10_38(format!("{}", -10_i128.pow(38)), -10_i128.pow(38))]
1240 #[case::max_minus_1(format!("{}", i128::MAX - 1), i128::MAX - 1)]
1241 #[case::max(format!("{}", i128::MAX), i128::MAX)]
1242 #[case::min_plus_1(format!("{}", i128::MIN + 1), i128::MIN + 1)]
1243 #[case::min(format!("{}", i128::MIN), i128::MIN)]
1244 fn test_content_parse_i128_ok(#[case] input: impl AsRef<str>, #[case] expect: i128) {
1245 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1246 assert_eq!(Token::Num, an.next());
1247 let content = an.content();
1248 assert_eq!(Ok(expect), content.parse_i128());
1249 assert_eq!(Ok(expect), lexical::Content::parse_i128(&content));
1250 }
1251
1252 #[cfg(feature = "num_ext")]
1253 #[rstest]
1254 #[case::decimal_zero("10.0", NumError::Format)]
1255 #[case::decimal("3.14159", NumError::Format)]
1256 #[case::exponent_zero("0e0", NumError::Format)]
1257 #[case::exponent_positive("10E+1", NumError::Format)]
1258 #[case::exponent_negative("1E-98", NumError::Format)]
1259 #[case::range_i128_max_plus_1(format!("{}", i128::MAX as u128 + 1), NumError::Range)]
1260 #[case::range_u128_max(format!("{}", u128::MAX), NumError::Range)]
1261 fn test_content_parse_i128_err(#[case] input: impl AsRef<str>, #[case] expect: NumError) {
1262 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1263 assert_eq!(Token::Num, an.next());
1264 let content = an.content();
1265 assert_eq!(Err(expect), content.parse_i128());
1266 assert_eq!(Err(expect), lexical::Content::parse_i128(&content));
1267 }
1268
1269 #[cfg(feature = "num")]
1270 #[rstest]
1271 #[case::zero("0", 0.0)]
1272 #[case::minus_zero("-0", 0.0)]
1273 #[case::one("1", 1.0)]
1274 #[case::minus_one("-1", -1.0)]
1275 #[case::forty_two("42", 42.0)]
1276 #[case::pi("3.14159", 3.14159)]
1277 #[case::negative_decimal("-2.5", -2.5)]
1278 #[case::exponent_zero("0e0", 0.0)]
1279 #[case::exponent_positive("1e2", 100.0)]
1280 #[case::exponent_negative("1e-2", 0.01)]
1281 #[case::exponent_upper("1E2", 100.0)]
1282 #[case::exponent_plus_sign("1e+2", 100.0)]
1283 #[case::decimal_and_exponent("1.5e2", 150.0)]
1284 #[case::large_integer("9876543210", 9876543210.0)]
1285 #[case::f64_max(format!("{}", f64::MAX), f64::MAX)]
1286 #[case::f64_min_positive(format!("{}", f64::MIN_POSITIVE), f64::MIN_POSITIVE)]
1287 #[case::subnormal("5e-324", 5e-324)]
1288 fn test_content_parse_f64_ok(#[case] input: impl AsRef<str>, #[case] expect: f64) {
1289 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1290 assert_eq!(Token::Num, an.next());
1291 let content = an.content();
1292 assert_eq!(Ok(expect), content.parse_f64());
1293 assert_eq!(Ok(expect), lexical::Content::parse_f64(&content));
1294 }
1295
1296 #[cfg(feature = "num")]
1297 #[rstest]
1298 #[case::range_positive_overflow("1e309", NumError::Range)]
1299 #[case::range_negative_overflow("-1e309", NumError::Range)]
1300 fn test_content_parse_f64_err(#[case] input: impl AsRef<str>, #[case] expect: NumError) {
1301 let mut an = FixedAnalyzer::new(input.as_ref().as_bytes().to_vec());
1302 assert_eq!(Token::Num, an.next());
1303 let content = an.content();
1304 assert_eq!(Err(expect), content.parse_f64());
1305 assert_eq!(Err(expect), lexical::Content::parse_f64(&content));
1306 }
1307
1308 #[rstest]
1309 #[case(
1310 ErrorKind::BadSurrogate { first: 0xd800, second: Some(0xd800), },
1311 "bad Unicode escape sequence surrogate pair: high surrogate '\\uD800' followed by invalid low surrogate '\\uD800' at line",
1312 )]
1313 #[case(
1314 ErrorKind::BadUtf8ContByte { seq_len: 3, offset: 2, value: 0x80 },
1315 "bad UTF-8 continuation byte 0x80 in 3-byte UTF-8 sequence (byte #2) at line",
1316 )]
1317 #[case(
1318 ErrorKind::UnexpectedByte { token: None, expect: Expect::TokenStartChar, actual: b'e' },
1319 "expected token start character but got character 'e' (ASCII 0x65) at line",
1320 )]
1321 #[case(
1322 ErrorKind::UnexpectedEof(Token::LitNull),
1323 "unexpected EOF in null token at line"
1324 )]
1325 fn test_error(#[case] kind: ErrorKind, #[case] expect: &str) {
1326 let pos = Pos::new(10, 2, 5);
1327 let err = Error { kind, pos };
1328
1329 assert_eq!(kind, err.kind());
1330 assert_eq!(kind, lexical::Error::kind(&err));
1331 assert_eq!(pos, *err.pos());
1332 assert_eq!(pos, *lexical::Error::pos(&err));
1333 assert!(err.source().is_none());
1334
1335 let actual = format!("{err}");
1336 assert!(
1337 actual.starts_with(expect),
1338 "expected {actual:?} to start with {expect:?}"
1339 );
1340 }
1341
1342 #[test]
1343 fn test_analyzer_initial_state_content() {
1344 let an = FixedAnalyzer::new(vec![]);
1345
1346 for _ in 0..5 {
1347 let content = an.content();
1348 assert_eq!("", content.literal());
1349 assert!(!content.is_escaped());
1350 assert_eq!("", content.unescaped());
1351
1352 let content = an.try_content().unwrap();
1353 assert_eq!("", content.literal());
1354 assert!(!content.is_escaped());
1355 assert_eq!("", content.unescaped());
1356 }
1357 }
1358
1359 #[test]
1360 #[should_panic(
1361 expected = "no error: last `next()` did not return `Token::Err` (use `content()` instead)"
1362 )]
1363 fn test_analyzer_initial_state_err() {
1364 let _ = FixedAnalyzer::new(vec![]).err();
1365 }
1366
1367 #[test]
1368 fn test_analyzer_clone_forks_state() {
1369 let mut analyzer = FixedAnalyzer::new(&b"[1,2]"[..]);
1370 assert_eq!(Token::ArrBegin, analyzer.next());
1371
1372 let mut fork = analyzer.clone();
1373
1374 assert_eq!(Token::Num, analyzer.next());
1375 assert_eq!("1", analyzer.content().literal());
1376 assert_eq!(Token::ValueSep, analyzer.next());
1377
1378 assert_eq!(Token::Num, fork.next());
1379 assert_eq!("1", fork.content().literal());
1380 assert_eq!(Token::ValueSep, fork.next());
1381
1382 assert_eq!(Token::Num, analyzer.next());
1383 assert_eq!("2", analyzer.content().literal());
1384 assert_eq!(Token::ArrEnd, analyzer.next());
1385 assert_eq!(Token::Eof, analyzer.next());
1386 }
1387
1388 #[rstest]
1389 #[case("", Token::Eof, None)]
1390 #[case("{", Token::ObjBegin, None)]
1391 #[case("}", Token::ObjEnd, None)]
1392 #[case("[", Token::ArrBegin, None)]
1393 #[case("]", Token::ArrEnd, None)]
1394 #[case(":", Token::NameSep, None)]
1395 #[case(",", Token::ValueSep, None)]
1396 #[case("false", Token::LitFalse, None)]
1397 #[case("null", Token::LitNull, None)]
1398 #[case("true", Token::LitTrue, None)]
1399 #[case("0", Token::Num, None)]
1400 #[case("-0", Token::Num, None)]
1401 #[case("1", Token::Num, None)]
1402 #[case("-1", Token::Num, None)]
1403 #[case("12", Token::Num, None)]
1404 #[case("-12", Token::Num, None)]
1405 #[case("0.0", Token::Num, None)]
1406 #[case("-0.0", Token::Num, None)]
1407 #[case("0.123456789", Token::Num, None)]
1408 #[case("-123.456789", Token::Num, None)]
1409 #[case("0E0", Token::Num, None)]
1410 #[case("0e0", Token::Num, None)]
1411 #[case("0E+0", Token::Num, None)]
1412 #[case("0e+0", Token::Num, None)]
1413 #[case("0E-0", Token::Num, None)]
1414 #[case("0e-0", Token::Num, None)]
1415 #[case("0.0E0", Token::Num, None)]
1416 #[case("0.0e0", Token::Num, None)]
1417 #[case("0.0E+0", Token::Num, None)]
1418 #[case("0.0e+0", Token::Num, None)]
1419 #[case("0.0E0", Token::Num, None)]
1420 #[case("0.0e0", Token::Num, None)]
1421 #[case("0E0", Token::Num, None)]
1422 #[case("0e0", Token::Num, None)]
1423 #[case("-0E+0", Token::Num, None)]
1424 #[case("-0e+0", Token::Num, None)]
1425 #[case("-0E-0", Token::Num, None)]
1426 #[case("-0e-0", Token::Num, None)]
1427 #[case("-0.0E0", Token::Num, None)]
1428 #[case("-0.0e0", Token::Num, None)]
1429 #[case("-0.0E+0", Token::Num, None)]
1430 #[case("-0.0e+0", Token::Num, None)]
1431 #[case("-0.0E0", Token::Num, None)]
1432 #[case("-0.0e0", Token::Num, None)]
1433 #[case("123E456", Token::Num, None)]
1434 #[case("123e456", Token::Num, None)]
1435 #[case("123.456E+7", Token::Num, None)]
1436 #[case("123.456e+7", Token::Num, None)]
1437 #[case("123.456E-89", Token::Num, None)]
1438 #[case("123.456e-89", Token::Num, None)]
1439 #[case("-123E456", Token::Num, None)]
1440 #[case("-123e456", Token::Num, None)]
1441 #[case("-123.456E+7", Token::Num, None)]
1442 #[case("-123.456e+7", Token::Num, None)]
1443 #[case("-123.456E-89", Token::Num, None)]
1444 #[case("-123.456e-89", Token::Num, None)]
1445 #[case(r#""""#, Token::Str, None)]
1446 #[case(r#"" ""#, Token::Str, None)]
1447 #[case(r#""foo""#, Token::Str, None)]
1448 #[case(r#""The quick brown fox jumped over the lazy dog!""#, Token::Str, None)]
1449 #[case(r#""\"""#, Token::Str, Some(r#"""""#))]
1450 #[case(r#""\\""#, Token::Str, Some(r#""\""#))]
1451 #[case(r#""\/""#, Token::Str, Some(r#""/""#))]
1452 #[case(r#""\t""#, Token::Str, Some("\"\t\""))]
1453 #[case(r#""\r""#, Token::Str, Some("\"\r\""))]
1454 #[case(r#""\n""#, Token::Str, Some("\"\n\""))]
1455 #[case(r#""\f""#, Token::Str, Some("\"\u{000c}\""))]
1456 #[case(r#""\b""#, Token::Str, Some("\"\u{0008}\""))]
1457 #[case(r#""\r\n""#, Token::Str, Some("\"\r\n\""))]
1458 #[case(r#""\u0000""#, Token::Str, Some("\"\u{0000}\""))]
1459 #[case(r#""\u001f""#, Token::Str, Some("\"\u{001f}\""))]
1460 #[case(r#""\u0020""#, Token::Str, Some(r#"" ""#))]
1461 #[case(r#""\u007E""#, Token::Str, Some(r#""~""#))]
1462 #[case(r#""\u007F""#, Token::Str, Some("\"\u{007f}\""))]
1463 #[case(r#""\u0080""#, Token::Str, Some("\"\u{0080}\""))]
1464 #[case(r#""\u0100""#, Token::Str, Some("\"\u{0100}\""))]
1465 #[case(r#""\ud7FF""#, Token::Str, Some("\"\u{d7ff}\""))]
1466 #[case(r#""\uE000""#, Token::Str, Some("\"\u{e000}\""))]
1467 #[case(r#""\ufDCf""#, Token::Str, Some("\"\u{fdcf}\""))]
1468 #[case(r#""\uFdeF""#, Token::Str, Some("\"\u{fdef}\""))]
1469 #[case(r#""\ufffd""#, Token::Str, Some("\"\u{fffd}\""))]
1470 #[case(r#""\uFFFE""#, Token::Str, Some("\"\u{fffe}\""))]
1471 #[case(r#""\uFFFF""#, Token::Str, Some("\"\u{ffff}\""))]
1472 #[case(r#""\ud800\udc00""#, Token::Str, Some("\"\u{10000}\""))] #[case(r#""\uD800\uDFFF""#, Token::Str, Some("\"\u{103ff}\""))] #[case(r#""\uDBFF\uDC00""#, Token::Str, Some("\"\u{10fc00}\""))] #[case(r#""\udbFf\udfff""#, Token::Str, Some("\"\u{10ffff}\""))] #[case(r#""\u0061b""#, Token::Str, Some(r#""ab""#))]
1477 #[case(r#""\uD800\uDC00a""#, Token::Str, Some("\"\u{10000}a\""))]
1478 #[case(r#""hello\nworld""#, Token::Str, Some("\"hello\nworld\""))]
1479 #[case(" ", Token::White, None)]
1480 #[case("\t", Token::White, None)]
1481 #[case(" ", Token::White, None)]
1482 #[case("\t\t", Token::White, None)]
1483 #[case(" \t \t \t \t\t", Token::White, None)]
1484 fn test_analyzer_single_token(
1485 #[case] input: &str,
1486 #[case] expect: Token,
1487 #[case] unescaped: Option<&str>,
1488 ) {
1489 {
1491 let mut an = FixedAnalyzer::new(input.as_bytes());
1492 assert_eq!(Pos::default(), *an.pos());
1493
1494 assert_eq!(expect, an.next());
1495 assert_eq!(Pos::default(), *an.pos());
1496
1497 let content = an.content();
1498 assert_eq!(input, content.literal());
1499 assert_eq!(unescaped.is_some(), content.is_escaped());
1500 if let Some(u) = unescaped {
1501 assert_eq!(u, content.unescaped());
1502 } else {
1503 assert_eq!(input, content.unescaped());
1504 }
1505
1506 assert_eq!(Token::Eof, an.next());
1507 assert_eq!(
1508 Pos {
1509 offset: input.len(),
1510 line: 1,
1511 col: input.len() + 1
1512 },
1513 *an.pos()
1514 );
1515
1516 assert_eq!(Token::Eof, an.next());
1517 assert_eq!(
1518 Pos {
1519 offset: input.len(),
1520 line: 1,
1521 col: input.len() + 1
1522 },
1523 *an.pos()
1524 );
1525 }
1526
1527 {
1529 let mut an = FixedAnalyzer::new(input.as_bytes());
1530 assert_eq!(Pos::default(), *an.pos());
1531
1532 assert_eq!(expect, an.next());
1533 assert_eq!(Pos::default(), *an.pos());
1534
1535 assert_eq!(Token::Eof, an.next());
1536 assert_eq!(
1537 Pos {
1538 offset: input.len(),
1539 line: 1,
1540 col: input.len() + 1
1541 },
1542 *an.pos()
1543 );
1544
1545 assert_eq!(Token::Eof, an.next());
1546 assert_eq!(
1547 Pos {
1548 offset: input.len(),
1549 line: 1,
1550 col: input.len() + 1
1551 },
1552 *an.pos()
1553 );
1554 }
1555 }
1556
1557 #[rstest]
1558 #[case("1".repeat(INLINE_LEN-1), Token::Num, None)]
1559 #[case("2".repeat(INLINE_LEN), Token::Num, None)]
1560 #[case("3".repeat(INLINE_LEN+1), Token::Num, None)]
1561 #[case(format!(r#""{}""#, "a".repeat(INLINE_LEN-3)), Token::Str, None)]
1562 #[case(format!(r#""{}""#, "b".repeat(INLINE_LEN-2)), Token::Str, None)]
1563 #[case(format!(r#""{}""#, "c".repeat(INLINE_LEN-1)), Token::Str, None)]
1564 #[case(format!(r#""{}""#, r#"\/"#.repeat(INLINE_LEN/2)), Token::Str, Some(format!(r#""{}""#, "/".repeat(INLINE_LEN/2))))]
1565 #[case(" ".repeat(INLINE_LEN-1), Token::White, None)]
1566 #[case("\t".repeat(INLINE_LEN), Token::White, None)]
1567 #[case(" ".repeat(INLINE_LEN+1), Token::White, None)]
1568 #[case(" \t".repeat(INLINE_LEN/2+1), Token::White, None)]
1569 fn test_analyzer_single_token_inline_len_boundary(
1570 #[case] input: String,
1571 #[case] expect: Token,
1572 #[case] unescaped: Option<String>,
1573 ) {
1574 let mut an = FixedAnalyzer::new(input.as_bytes());
1575 assert_eq!(Pos::default(), *an.pos());
1576
1577 assert_eq!(expect, an.next());
1578 assert_eq!(Pos::default(), *an.pos());
1579
1580 let content = an.content();
1581 assert_eq!(input, content.literal());
1582 assert_eq!(unescaped.is_some(), content.is_escaped());
1583 if let Some(u) = unescaped {
1584 assert_eq!(u, content.unescaped());
1585 } else {
1586 assert_eq!(input, content.unescaped());
1587 }
1588
1589 assert_eq!(Token::Eof, an.next());
1590 assert_eq!(
1591 Pos {
1592 offset: input.len(),
1593 line: 1,
1594 col: input.len() + 1
1595 },
1596 *an.pos()
1597 );
1598
1599 assert_eq!(Token::Eof, an.next());
1600 assert_eq!(
1601 Pos {
1602 offset: input.len(),
1603 line: 1,
1604 col: input.len() + 1
1605 },
1606 *an.pos()
1607 );
1608 }
1609
1610 #[rstest]
1611 #[case(r#"["#)]
1612 #[case(r#"]"#)]
1613 #[case(r#"false"#)]
1614 #[case(r#":"#)]
1615 #[case(r#"null"#)]
1616 #[case(r#"3.14159e+0"#)]
1617 #[case(r#"{"#)]
1618 #[case(r#"}"#)]
1619 #[case(r#""foo\/\u1234\/bar""#)]
1620 #[case(r#"true"#)]
1621 #[case(r#","#)]
1622 #[case("\n\n\n ")]
1623 #[should_panic(
1624 expected = "no error: last `next()` did not return `Token::Err` (use `content()` instead)"
1625 )]
1626 fn test_analyzer_single_token_panic_no_err(#[case] input: &str) {
1627 let mut an = FixedAnalyzer::new(input.as_bytes());
1628
1629 let token = an.next();
1630 assert!(!token.is_terminal(), "input = {input:?}, token = {token:?}");
1631
1632 let _ = an.err();
1633 }
1634
1635 #[rstest]
1636 #[case("\"\u{0020}\"")]
1637 #[case("\"\u{007f}\"")] #[case("\"\u{0080}\"")] #[case("\"\u{07ff}\"")] #[case("\"\u{0800}\"")] #[case("\"\u{d7ff}\"")] #[case("\"\u{e000}\"")] #[case("\"\u{ffff}\"")] #[case("\"\u{10000}\"")] #[case("\"\u{10ffff}\"")] #[case("\"\u{3f086}\"")] fn test_analyzer_utf8_char_1(#[case] input: &str) {
1648 {
1650 let mut an = FixedAnalyzer::new(input.as_bytes());
1651 assert_eq!(Pos::default(), *an.pos());
1652
1653 assert_eq!(Token::Str, an.next());
1654 assert_eq!(Pos::default(), *an.pos());
1655
1656 let content = an.content();
1657 assert_eq!(input, content.literal());
1658 assert!(!content.is_escaped());
1659 assert_eq!(input, content.unescaped());
1660
1661 assert_eq!(Token::Eof, an.next());
1662 assert_eq!(
1663 Pos {
1664 offset: input.len(),
1665 line: 1,
1666 col: 4,
1667 },
1668 *an.pos()
1669 );
1670
1671 assert_eq!(Token::Eof, an.next());
1672 assert_eq!(
1673 Pos {
1674 offset: input.len(),
1675 line: 1,
1676 col: 4,
1677 },
1678 *an.pos()
1679 );
1680 }
1681
1682 {
1684 let mut an = FixedAnalyzer::new(input.as_bytes());
1685 assert_eq!(Pos::default(), *an.pos());
1686
1687 assert_eq!(Token::Str, an.next());
1688 assert_eq!(Pos::default(), *an.pos());
1689
1690 assert_eq!(Token::Eof, an.next());
1691 assert_eq!(
1692 Pos {
1693 offset: input.len(),
1694 line: 1,
1695 col: 4,
1696 },
1697 *an.pos()
1698 );
1699
1700 assert_eq!(Token::Eof, an.next());
1701 assert_eq!(
1702 Pos {
1703 offset: input.len(),
1704 line: 1,
1705 col: 4,
1706 },
1707 *an.pos()
1708 );
1709 }
1710 }
1711
1712 #[rstest]
1713 #[case::two_1("\"\u{00e4}a\"")]
1715 #[case::two_2("\"\u{00e4}\u{00e4}\"")]
1716 #[case::two_3("\"\u{00e4}\u{3042}\"")]
1717 #[case::two_4("\"\u{00e4}\u{10000}\"")]
1718 #[case::three_1("\"\u{3042}a\"")]
1720 #[case::three_2("\"\u{3042}\u{00e4}\"")]
1721 #[case::three_3("\"\u{3042}\u{3042}\"")]
1722 #[case::three_4("\"\u{3042}\u{10000}\"")]
1723 #[case::four_1("\"\u{10000}a\"")]
1725 #[case::four_2("\"\u{10000}\u{00e4}\"")]
1726 #[case::four_3("\"\u{10000}\u{3042}\"")]
1727 #[case::four_4("\"\u{10000}\u{10000}\"")]
1728 fn test_analyzer_utf8_char_2(#[case] input: &str) {
1729 {
1731 let mut an = FixedAnalyzer::new(input.as_bytes());
1732 assert_eq!(Pos::default(), *an.pos());
1733
1734 assert_eq!(Token::Str, an.next());
1735 assert_eq!(Pos::default(), *an.pos());
1736
1737 let content = an.content();
1738 assert_eq!(input, content.literal());
1739 assert!(!content.is_escaped());
1740 assert_eq!(input, content.unescaped());
1741
1742 assert_eq!(Token::Eof, an.next());
1743 assert_eq!(
1744 Pos {
1745 offset: input.len(),
1746 line: 1,
1747 col: 5,
1748 },
1749 *an.pos()
1750 );
1751
1752 assert_eq!(Token::Eof, an.next());
1753 assert_eq!(
1754 Pos {
1755 offset: input.len(),
1756 line: 1,
1757 col: 5,
1758 },
1759 *an.pos()
1760 );
1761 }
1762
1763 {
1765 let mut an = FixedAnalyzer::new(input.as_bytes());
1766 assert_eq!(Pos::default(), *an.pos());
1767
1768 assert_eq!(Token::Str, an.next());
1769 assert_eq!(Pos::default(), *an.pos());
1770
1771 assert_eq!(Token::Eof, an.next());
1772 assert_eq!(
1773 Pos {
1774 offset: input.len(),
1775 line: 1,
1776 col: 5,
1777 },
1778 *an.pos()
1779 );
1780
1781 assert_eq!(Token::Eof, an.next());
1782 assert_eq!(
1783 Pos {
1784 offset: input.len(),
1785 line: 1,
1786 col: 5,
1787 },
1788 *an.pos()
1789 );
1790 }
1791 }
1792
1793 #[rstest]
1794 #[case("\n", 2, 1)]
1795 #[case("\n\n", 3, 1)]
1796 #[case("\r", 2, 1)]
1797 #[case("\r\r", 3, 1)]
1798 #[case("\r\n", 2, 1)]
1799 #[case("\n\r", 3, 1)]
1800 #[case("\n\n\r\r", 5, 1)]
1801 #[case("\r\n\r", 3, 1)]
1802 #[case("\n\r\n", 3, 1)]
1803 #[case(" \n", 2, 1)]
1804 #[case("\n ", 2, 2)]
1805 #[case(" \r", 2, 1)]
1806 #[case("\r ", 2, 2)]
1807 #[case("\t\n", 2, 1)]
1808 #[case("\n ", 2, 2)]
1809 #[case("\t\r", 2, 1)]
1810 #[case("\r\t", 2, 2)]
1811 fn test_analyzer_whitespace_multiline(
1812 #[case] input: &str,
1813 #[case] line: usize,
1814 #[case] col: usize,
1815 ) {
1816 {
1818 let mut an = FixedAnalyzer::new(input.as_bytes());
1819 assert_eq!(Pos::default(), *an.pos());
1820
1821 assert_eq!(Token::White, an.next());
1822 assert_eq!(Pos::default(), *an.pos());
1823
1824 let content = an.content();
1825 assert_eq!(input, content.literal());
1826 assert!(!content.is_escaped());
1827 assert_eq!(input, content.unescaped());
1828
1829 assert_eq!(Token::Eof, an.next());
1830 assert_eq!(
1831 Pos {
1832 offset: input.len(),
1833 line,
1834 col
1835 },
1836 *an.pos()
1837 );
1838 }
1839
1840 {
1842 let mut an = FixedAnalyzer::new(input.as_bytes());
1843 assert_eq!(Pos::default(), *an.pos());
1844
1845 assert_eq!(Token::White, an.next());
1846 assert_eq!(Pos::default(), *an.pos());
1847
1848 assert_eq!(Token::Eof, an.next());
1849 assert_eq!(
1850 Pos {
1851 offset: input.len(),
1852 line,
1853 col
1854 },
1855 *an.pos()
1856 );
1857 }
1858 }
1859
1860 #[rstest]
1861 #[case("", T::t(Token::Eof, ""), T::t(Token::Eof, ""), 1, 1)]
1862 #[case("{{", T::t(Token::ObjBegin, "{"), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
1866 #[case("{}", T::t(Token::ObjBegin, "{"), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
1867 #[case("{[", T::t(Token::ObjBegin, "{"), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
1868 #[case("{]", T::t(Token::ObjBegin, "{"), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
1869 #[case("{:", T::t(Token::ObjBegin, "{"), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
1870 #[case("{,", T::t(Token::ObjBegin, "{"), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
1871 #[case("{false", T::t(Token::ObjBegin, "{"), T::t(Token::LitFalse, "false").pos(1, 1, 2), 1, 7)]
1872 #[case("{null", T::t(Token::ObjBegin, "{"), T::t(Token::LitNull, "null").pos(1, 1, 2), 1, 6)]
1873 #[case("{true", T::t(Token::ObjBegin, "{"), T::t(Token::LitTrue, "true").pos(1, 1, 2), 1, 6)]
1874 #[case("{0", T::t(Token::ObjBegin, "{"), T::t(Token::Num, "0").pos(1, 1, 2), 1, 3)]
1875 #[case("{-1.9", T::t(Token::ObjBegin, "{"), T::t(Token::Num, "-1.9").pos(1, 1, 2), 1, 6)]
1876 #[case("{3.14e+0", T::t(Token::ObjBegin, "{"), T::t(Token::Num, "3.14e+0").pos(1, 1, 2), 1, 9)]
1877 #[case(r#"{"""#, T::t(Token::ObjBegin, "{"), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
1878 #[case(r#"{"foo""#, T::t(Token::ObjBegin, "{"), T::t(Token::Str, r#""foo""#).pos(1, 1, 2), 1, 7)]
1879 #[case(r#"{"hello\u0020there,\nworld!""#, T::t(Token::ObjBegin, "{"), T::t(Token::Str, r#""hello\u0020there,\nworld!""#).pos(1, 1, 2).unescaped("\"hello there,\nworld!\""), 1,29)]
1880 #[case("{ ", T::t(Token::ObjBegin, "{"), T::t(Token::White, " ").pos(1, 1, 2), 1, 3)]
1881 #[case("{\t\t\r\n\n ", T::t(Token::ObjBegin, "{"), T::t(Token::White, "\t\t\r\n\n ").pos(1, 1, 2), 3, 2)]
1882 #[case("}{", T::t(Token::ObjEnd, "}"), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
1886 #[case("}}", T::t(Token::ObjEnd, "}"), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
1887 #[case("}[", T::t(Token::ObjEnd, "}"), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
1888 #[case("}]", T::t(Token::ObjEnd, "}"), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
1889 #[case("}:", T::t(Token::ObjEnd, "}"), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
1890 #[case("},", T::t(Token::ObjEnd, "}"), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
1891 #[case("}false", T::t(Token::ObjEnd, "}"), T::t(Token::LitFalse, "false").pos(1, 1, 2), 1, 7)]
1892 #[case("}null", T::t(Token::ObjEnd, "}"), T::t(Token::LitNull, "null").pos(1, 1, 2), 1, 6)]
1893 #[case("}true", T::t(Token::ObjEnd, "}"), T::t(Token::LitTrue, "true").pos(1, 1, 2), 1, 6)]
1894 #[case("}0", T::t(Token::ObjEnd, "}"), T::t(Token::Num, "0").pos(1, 1, 2), 1, 3)]
1895 #[case("}-1.9", T::t(Token::ObjEnd, "}"), T::t(Token::Num, "-1.9").pos(1, 1, 2), 1, 6)]
1896 #[case("}3.14e+0", T::t(Token::ObjEnd, "}"), T::t(Token::Num, "3.14e+0").pos(1, 1, 2), 1, 9)]
1897 #[case(r#"}"""#, T::t(Token::ObjEnd, "}"), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
1898 #[case(r#"}"foo""#, T::t(Token::ObjEnd, "}"), T::t(Token::Str, r#""foo""#).pos(1, 1, 2), 1, 7)]
1899 #[case(r#"}"hello\u0020there,\nworld!""#, T::t(Token::ObjEnd, "}"), T::t(Token::Str, r#""hello\u0020there,\nworld!""#).pos(1, 1, 2).unescaped("\"hello there,\nworld!\""), 1,29)]
1900 #[case("} ", T::t(Token::ObjEnd, "}"), T::t(Token::White, " ").pos(1, 1, 2), 1, 3)]
1901 #[case("}\t\t\r\n\n ", T::t(Token::ObjEnd, "}"), T::t(Token::White, "\t\t\r\n\n ").pos(1, 1, 2), 3, 2)]
1902 #[case("[{", T::t(Token::ArrBegin, "["), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
1906 #[case("[}", T::t(Token::ArrBegin, "["), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
1907 #[case("[[", T::t(Token::ArrBegin, "["), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
1908 #[case("[]", T::t(Token::ArrBegin, "["), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
1909 #[case("[:", T::t(Token::ArrBegin, "["), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
1910 #[case("[,", T::t(Token::ArrBegin, "["), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
1911 #[case("[false", T::t(Token::ArrBegin, "["), T::t(Token::LitFalse, "false").pos(1, 1, 2), 1, 7)]
1912 #[case("[null", T::t(Token::ArrBegin, "["), T::t(Token::LitNull, "null").pos(1, 1, 2), 1, 6)]
1913 #[case("[true", T::t(Token::ArrBegin, "["), T::t(Token::LitTrue, "true").pos(1, 1, 2), 1, 6)]
1914 #[case("[0", T::t(Token::ArrBegin, "["), T::t(Token::Num, "0").pos(1, 1, 2), 1, 3)]
1915 #[case("[-1.9", T::t(Token::ArrBegin, "["), T::t(Token::Num, "-1.9").pos(1, 1, 2), 1, 6)]
1916 #[case("[3.14e+0", T::t(Token::ArrBegin, "["), T::t(Token::Num, "3.14e+0").pos(1, 1, 2), 1, 9)]
1917 #[case(r#"["""#, T::t(Token::ArrBegin, "["), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
1918 #[case(r#"["foo""#, T::t(Token::ArrBegin, "["), T::t(Token::Str, r#""foo""#).pos(1, 1, 2), 1, 7)]
1919 #[case(r#"["hello\u0020there,\nworld!""#, T::t(Token::ArrBegin, "["), T::t(Token::Str, r#""hello\u0020there,\nworld!""#).pos(1, 1, 2).unescaped("\"hello there,\nworld!\""), 1,29)]
1920 #[case("[ ", T::t(Token::ArrBegin, "["), T::t(Token::White, " ").pos(1, 1, 2), 1, 3)]
1921 #[case("[\t\t\r\n\n ", T::t(Token::ArrBegin, "["), T::t(Token::White, "\t\t\r\n\n ").pos(1, 1, 2), 3, 2)]
1922 #[case("]{", T::t(Token::ArrEnd, "]"), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
1926 #[case("]}", T::t(Token::ArrEnd, "]"), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
1927 #[case("][", T::t(Token::ArrEnd, "]"), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
1928 #[case("]]", T::t(Token::ArrEnd, "]"), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
1929 #[case("]:", T::t(Token::ArrEnd, "]"), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
1930 #[case("],", T::t(Token::ArrEnd, "]"), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
1931 #[case("]false", T::t(Token::ArrEnd, "]"), T::t(Token::LitFalse, "false").pos(1, 1, 2), 1, 7)]
1932 #[case("]null", T::t(Token::ArrEnd, "]"), T::t(Token::LitNull, "null").pos(1, 1, 2), 1, 6)]
1933 #[case("]true", T::t(Token::ArrEnd, "]"), T::t(Token::LitTrue, "true").pos(1, 1, 2), 1, 6)]
1934 #[case("]0", T::t(Token::ArrEnd, "]"), T::t(Token::Num, "0").pos(1, 1, 2), 1, 3)]
1935 #[case("]-1.9", T::t(Token::ArrEnd, "]"), T::t(Token::Num, "-1.9").pos(1, 1, 2), 1, 6)]
1936 #[case("]31.4e-1", T::t(Token::ArrEnd, "]"), T::t(Token::Num, "31.4e-1").pos(1, 1, 2), 1, 9)]
1937 #[case(r#"]"""#, T::t(Token::ArrEnd, "]"), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
1938 #[case(r#"]"foo""#, T::t(Token::ArrEnd, "]"), T::t(Token::Str, r#""foo""#).pos(1, 1, 2), 1, 7)]
1939 #[case(r#"]"hello\u0020there,\nworld!""#, T::t(Token::ArrEnd, "]"), T::t(Token::Str, r#""hello\u0020there,\nworld!""#).pos(1, 1, 2).unescaped("\"hello there,\nworld!\""), 1,29)]
1940 #[case("] ", T::t(Token::ArrEnd, "]"), T::t(Token::White, " ").pos(1, 1, 2), 1, 3)]
1941 #[case("]\t\t\r\n\n ", T::t(Token::ArrEnd, "]"), T::t(Token::White, "\t\t\r\n\n ").pos(1, 1, 2), 3, 2)]
1942 #[case(":{", T::t(Token::NameSep, ":"), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
1946 #[case(":}", T::t(Token::NameSep, ":"), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
1947 #[case(":[", T::t(Token::NameSep, ":"), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
1948 #[case(":]", T::t(Token::NameSep, ":"), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
1949 #[case("::", T::t(Token::NameSep, ":"), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
1950 #[case(":,", T::t(Token::NameSep, ":"), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
1951 #[case(":false", T::t(Token::NameSep, ":"), T::t(Token::LitFalse, "false").pos(1, 1, 2), 1, 7)]
1952 #[case(":null", T::t(Token::NameSep, ":"), T::t(Token::LitNull, "null").pos(1, 1, 2), 1, 6)]
1953 #[case(":true", T::t(Token::NameSep, ":"), T::t(Token::LitTrue, "true").pos(1, 1, 2), 1, 6)]
1954 #[case(":0", T::t(Token::NameSep, ":"), T::t(Token::Num, "0").pos(1, 1, 2), 1, 3)]
1955 #[case(":-1.9", T::t(Token::NameSep, ":"), T::t(Token::Num, "-1.9").pos(1, 1, 2), 1, 6)]
1956 #[case(":31.4e-1", T::t(Token::NameSep, ":"), T::t(Token::Num, "31.4e-1").pos(1, 1, 2), 1, 9)]
1957 #[case(r#":"""#, T::t(Token::NameSep, ":"), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
1958 #[case(r#":"foo""#, T::t(Token::NameSep, ":"), T::t(Token::Str, r#""foo""#).pos(1, 1, 2), 1, 7)]
1959 #[case(r#":"hello\u0020there,\nworld!""#, T::t(Token::NameSep, ":"), T::t(Token::Str, r#""hello\u0020there,\nworld!""#).pos(1, 1, 2).unescaped("\"hello there,\nworld!\""), 1,29)]
1960 #[case(": ", T::t(Token::NameSep, ":"), T::t(Token::White, " ").pos(1, 1, 2), 1, 3)]
1961 #[case(":\t\t\r\n\n ", T::t(Token::NameSep, ":"), T::t(Token::White, "\t\t\r\n\n ").pos(1, 1, 2), 3, 2)]
1962 #[case(",{", T::t(Token::ValueSep, ","), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
1966 #[case(",}", T::t(Token::ValueSep, ","), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
1967 #[case(",[", T::t(Token::ValueSep, ","), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
1968 #[case(",]", T::t(Token::ValueSep, ","), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
1969 #[case(",:", T::t(Token::ValueSep, ","), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
1970 #[case(",,", T::t(Token::ValueSep, ","), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
1971 #[case(",false", T::t(Token::ValueSep, ","), T::t(Token::LitFalse, "false").pos(1, 1, 2), 1, 7)]
1972 #[case(",null", T::t(Token::ValueSep, ","), T::t(Token::LitNull, "null").pos(1, 1, 2), 1, 6)]
1973 #[case(",true", T::t(Token::ValueSep, ","), T::t(Token::LitTrue, "true").pos(1, 1, 2), 1, 6)]
1974 #[case(",-0.0", T::t(Token::ValueSep, ","), T::t(Token::Num, "-0.0").pos(1, 1, 2), 1, 6)]
1975 #[case(",1.9", T::t(Token::ValueSep, ","), T::t(Token::Num, "1.9").pos(1, 1, 2), 1, 5)]
1976 #[case(",314e-2", T::t(Token::ValueSep, ","), T::t(Token::Num, "314e-2").pos(1, 1, 2), 1, 8)]
1977 #[case(r#","""#, T::t(Token::ValueSep, ","), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
1978 #[case(r#","foo""#, T::t(Token::ValueSep, ","), T::t(Token::Str, r#""foo""#).pos(1, 1, 2), 1, 7)]
1979 #[case(r#","hello\u0020there,\nworld!""#, T::t(Token::ValueSep, ","), T::t(Token::Str, r#""hello\u0020there,\nworld!""#).pos(1, 1, 2).unescaped("\"hello there,\nworld!\""), 1,29)]
1980 #[case(", ", T::t(Token::ValueSep, ","), T::t(Token::White, " ").pos(1, 1, 2), 1, 3)]
1981 #[case(",\t\t\r\n\n ", T::t(Token::ValueSep, ","), T::t(Token::White, "\t\t\r\n\n ").pos(1, 1, 2), 3, 2)]
1982 #[case("false{", T::t(Token::LitFalse, "false"), T::t(Token::ObjBegin, "{").pos(5, 1, 6), 1, 7)]
1986 #[case("false}", T::t(Token::LitFalse, "false"), T::t(Token::ObjEnd, "}").pos(5, 1, 6), 1, 7)]
1987 #[case("false[", T::t(Token::LitFalse, "false"), T::t(Token::ArrBegin, "[").pos(5, 1, 6), 1, 7)]
1988 #[case("false]", T::t(Token::LitFalse, "false"), T::t(Token::ArrEnd, "]").pos(5, 1, 6), 1, 7)]
1989 #[case("false:", T::t(Token::LitFalse, "false"), T::t(Token::NameSep, ":").pos(5, 1, 6), 1, 7)]
1990 #[case("false,", T::t(Token::LitFalse, "false"), T::t(Token::ValueSep, ",").pos(5, 1, 6), 1, 7)]
1991 #[case("false ", T::t(Token::LitFalse, "false"), T::t(Token::White, " ").pos(5, 1, 6), 1, 7)]
1992 #[case("false\t", T::t(Token::LitFalse, "false"), T::t(Token::White, "\t").pos(5, 1, 6), 1, 7)]
1993 #[case("false\r", T::t(Token::LitFalse, "false"), T::t(Token::White, "\r").pos(5, 1, 6), 2, 1)]
1994 #[case("false\n", T::t(Token::LitFalse, "false"), T::t(Token::White, "\n").pos(5, 1, 6), 2, 1)]
1995 #[case("false\r\n", T::t(Token::LitFalse, "false"), T::t(Token::White, "\r\n").pos(5, 1, 6), 2, 1)]
1996 #[case("false\n\r", T::t(Token::LitFalse, "false"), T::t(Token::White, "\n\r").pos(5, 1, 6), 3, 1)]
1997 #[case("false\r\n ", T::t(Token::LitFalse, "false"), T::t(Token::White, "\r\n ").pos(5, 1, 6), 2, 2)]
1998 #[case("false\n\r ", T::t(Token::LitFalse, "false"), T::t(Token::White, "\n\r ").pos(5, 1, 6), 3, 2)]
1999 #[case("false \r\n", T::t(Token::LitFalse, "false"), T::t(Token::White, " \r\n").pos(5, 1, 6), 2, 1)]
2000 #[case("false \n\r", T::t(Token::LitFalse, "false"), T::t(Token::White, " \n\r").pos(5, 1, 6), 3, 1)]
2001 #[case(r#"false"""#, T::t(Token::LitFalse, "false"), T::t(Token::Str, r#""""#).pos(5, 1, 6), 1, 8)]
2002 #[case("null{", T::t(Token::LitNull, "null"), T::t(Token::ObjBegin, "{").pos(4, 1, 5), 1, 6)]
2006 #[case("null}", T::t(Token::LitNull, "null"), T::t(Token::ObjEnd, "}").pos(4, 1, 5), 1, 6)]
2007 #[case("null[", T::t(Token::LitNull, "null"), T::t(Token::ArrBegin, "[").pos(4, 1, 5), 1, 6)]
2008 #[case("null]", T::t(Token::LitNull, "null"), T::t(Token::ArrEnd, "]").pos(4, 1, 5), 1, 6)]
2009 #[case("null:", T::t(Token::LitNull, "null"), T::t(Token::NameSep, ":").pos(4, 1, 5), 1, 6)]
2010 #[case("null,", T::t(Token::LitNull, "null"), T::t(Token::ValueSep, ",").pos(4, 1, 5), 1, 6)]
2011 #[case("null ", T::t(Token::LitNull, "null"), T::t(Token::White, " ").pos(4, 1, 5), 1, 6)]
2012 #[case("null\t", T::t(Token::LitNull, "null"), T::t(Token::White, "\t").pos(4, 1, 5), 1, 6)]
2013 #[case("null\r", T::t(Token::LitNull, "null"), T::t(Token::White, "\r").pos(4, 1, 5), 2, 1)]
2014 #[case("null\n", T::t(Token::LitNull, "null"), T::t(Token::White, "\n").pos(4, 1, 5), 2, 1)]
2015 #[case(r#"null"x""#, T::t(Token::LitNull, "null"), T::t(Token::Str, r#""x""#).pos(4, 1, 5), 1, 8)]
2016 #[case("true{", T::t(Token::LitTrue, "true"), T::t(Token::ObjBegin, "{").pos(4, 1, 5), 1, 6)]
2020 #[case("true}", T::t(Token::LitTrue, "true"), T::t(Token::ObjEnd, "}").pos(4, 1, 5), 1, 6)]
2021 #[case("true[", T::t(Token::LitTrue, "true"), T::t(Token::ArrBegin, "[").pos(4, 1, 5), 1, 6)]
2022 #[case("true]", T::t(Token::LitTrue, "true"), T::t(Token::ArrEnd, "]").pos(4, 1, 5), 1, 6)]
2023 #[case("true:", T::t(Token::LitTrue, "true"), T::t(Token::NameSep, ":").pos(4, 1, 5), 1, 6)]
2024 #[case("true,", T::t(Token::LitTrue, "true"), T::t(Token::ValueSep, ",").pos(4, 1, 5), 1, 6)]
2025 #[case("true ", T::t(Token::LitTrue, "true"), T::t(Token::White, " ").pos(4, 1, 5), 1, 6)]
2026 #[case("true\t", T::t(Token::LitTrue, "true"), T::t(Token::White, "\t").pos(4, 1, 5), 1, 6)]
2027 #[case("true\r", T::t(Token::LitTrue, "true"), T::t(Token::White, "\r").pos(4, 1, 5), 2, 1)]
2028 #[case("true\n", T::t(Token::LitTrue, "true"), T::t(Token::White, "\n").pos(4, 1, 5), 2, 1)]
2029 #[case(r#"true"🧶""#, T::t(Token::LitTrue, "true"), T::t(Token::Str, r#""🧶""#).pos(4, 1, 5), 1, 8)]
2030 #[case("0{", T::t(Token::Num, "0"), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
2034 #[case("0}", T::t(Token::Num, "0"), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
2035 #[case("0[", T::t(Token::Num, "0"), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
2036 #[case("0]", T::t(Token::Num, "0"), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
2037 #[case("0:", T::t(Token::Num, "0"), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
2038 #[case("0,", T::t(Token::Num, "0"), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
2039 #[case("0 ", T::t(Token::Num, "0"), T::t(Token::White, " ").pos(1, 1, 2), 1, 3)]
2040 #[case("0\t", T::t(Token::Num, "0"), T::t(Token::White, "\t").pos(1, 1, 2), 1, 3)]
2041 #[case("0\r", T::t(Token::Num, "0"), T::t(Token::White, "\r").pos(1, 1, 2), 2, 1)]
2042 #[case("0\n", T::t(Token::Num, "0"), T::t(Token::White, "\n").pos(1, 1, 2), 2, 1)]
2043 #[case(r#"0"""#, T::t(Token::Num, "0"), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
2044 #[case("1{", T::t(Token::Num, "1"), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
2045 #[case("-9}", T::t(Token::Num, "-9"), T::t(Token::ObjEnd, "}").pos(2, 1, 3), 1, 4)]
2046 #[case("0.0[", T::t(Token::Num, "0.0"), T::t(Token::ArrBegin, "[").pos(3, 1, 4), 1, 5)]
2047 #[case("-0]", T::t(Token::Num, "-0"), T::t(Token::ArrEnd, "]").pos(2, 1, 3), 1, 4)]
2048 #[case(r#"-0"a""#, T::t(Token::Num, "-0"), T::t(Token::Str, r#""a""#).pos(2, 1, 3), 1, 6)]
2049 #[case("-0.0123456789:", T::t(Token::Num, "-0.0123456789"), T::t(Token::NameSep, ":").pos(13, 1, 14), 1, 15)]
2050 #[case("123456789e10,", T::t(Token::Num, "123456789e10"), T::t(Token::ValueSep, ",").pos(12, 1, 13), 1, 14)]
2051 #[case("0e-1 ", T::t(Token::Num, "0e-1"), T::t(Token::White, " ").pos(4, 1, 5), 1, 6)]
2052 #[case("2e+3\t", T::t(Token::Num, "2e+3"), T::t(Token::White, "\t").pos(4, 1, 5), 1, 6)]
2053 #[case("-5e6\r", T::t(Token::Num, "-5e6"), T::t(Token::White, "\r").pos(4, 1, 5), 2, 1)]
2054 #[case("6.7e89\n", T::t(Token::Num, "6.7e89"), T::t(Token::White, "\n").pos(6, 1, 7), 2, 1)]
2055 #[case(r#"1"a""#, T::t(Token::Num, "1"), T::t(Token::Str, r#""a""#).pos(1, 1, 2), 1, 5)]
2056 #[case(r#"2.5"a""#, T::t(Token::Num, "2.5"), T::t(Token::Str, r#""a""#).pos(3, 1, 4), 1, 7)]
2057 #[case(r#"3e4"a""#, T::t(Token::Num, "3e4"), T::t(Token::Str, r#""a""#).pos(3, 1, 4), 1, 7)]
2058 #[case(r#"""{"#, T::t(Token::Str, r#""""#), T::t(Token::ObjBegin, "{").pos(2, 1, 3), 1, 4)]
2062 #[case(r#"""}"#, T::t(Token::Str, r#""""#), T::t(Token::ObjEnd, "}").pos(2, 1, 3), 1, 4)]
2063 #[case(r#"""["#, T::t(Token::Str, r#""""#), T::t(Token::ArrBegin, "[").pos(2, 1, 3), 1, 4)]
2064 #[case(r#"""]"#, T::t(Token::Str, r#""""#), T::t(Token::ArrEnd, "]").pos(2, 1, 3), 1, 4)]
2065 #[case(r#""":"#, T::t(Token::Str, r#""""#), T::t(Token::NameSep, ":").pos(2, 1, 3), 1, 4)]
2066 #[case(r#""","#, T::t(Token::Str, r#""""#), T::t(Token::ValueSep, ",").pos(2, 1, 3), 1, 4)]
2067 #[case(r#""" "#, T::t(Token::Str, r#""""#), T::t(Token::White, " ").pos(2, 1, 3), 1, 4)]
2068 #[case("\"\"\t", T::t(Token::Str, r#""""#), T::t(Token::White, "\t").pos(2, 1, 3), 1, 4)]
2069 #[case("\"\"\r", T::t(Token::Str, r#""""#), T::t(Token::White, "\r").pos(2, 1, 3), 2, 1)]
2070 #[case("\"\"\n", T::t(Token::Str, r#""""#), T::t(Token::White, "\n").pos(2, 1, 3), 2, 1)]
2071 #[case(r#""x"}"#, T::t(Token::Str, r#""x""#), T::t(Token::ObjEnd, "}").pos(3, 1, 4), 1, 5)]
2072 #[case(r#""foo bar"]"#, T::t(Token::Str, r#""foo bar""#), T::t(Token::ArrEnd, "]").pos(9, 1, 10), 1, 11)]
2073 #[case(r#""🧶":"#, T::t(Token::Str, r#""🧶""#), T::t(Token::NameSep, ":").pos(6, 1, 4), 1, 5)]
2074 #[case(r#""\"\t\r\n\\\/\u0020\"","#, T::t(Token::Str, r#""\"\t\r\n\\\/\u0020\"""#).unescaped("\"\"\t\r\n\\/ \"\""), T::t(Token::ValueSep, ",").pos(22, 1, 23), 1, 24)]
2075 #[case(r#""treble \uD834\uDD1E""clef""#, T::t(Token::Str, r#""treble \uD834\uDD1E""#).unescaped("\"treble 𝄞\""), T::t(Token::Str, r#""clef""#).pos(21, 1, 22), 1, 28)]
2076 #[case(r#""a"0e+12"#, T::t(Token::Str, r#""a""#), T::t(Token::Num, "0e+12").pos(3, 1, 4), 1, 9)]
2077 #[case(r#""❤😊"-0"#, T::t(Token::Str, r#""❤😊""#), T::t(Token::Num, "-0").pos(9, 1, 5), 1, 7)]
2078 #[case(r#""❤️😊"1"#, T::t(Token::Str, r#""❤️😊""#), T::t(Token::Num, "1").pos(12, 1, 6), 1, 7)]
2079 #[case(r#""""a""#, T::t(Token::Str, r#""""#), T::t(Token::Str, r#""a""#).pos(2, 1, 3), 1, 6)]
2080 #[case(r#""""café""#, T::t(Token::Str, r#""""#), T::t(Token::Str, r#""café""#).pos(2, 1, 3), 1, 9)]
2081 #[case(r#""a""""#, T::t(Token::Str, r#""a""#), T::t(Token::Str, r#""""#).pos(3, 1, 4), 1, 6)]
2082 #[case(r#""€10""""#, T::t(Token::Str, r#""€10""#), T::t(Token::Str, r#""""#).pos(7, 1, 6), 1, 8)]
2083 #[case(" {", T::t(Token::White, " "), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
2087 #[case(" }", T::t(Token::White, " "), T::t(Token::ObjEnd, "}").pos(1, 1, 2), 1, 3)]
2088 #[case(" [", T::t(Token::White, " "), T::t(Token::ArrBegin, "[").pos(1, 1, 2), 1, 3)]
2089 #[case(" ]", T::t(Token::White, " "), T::t(Token::ArrEnd, "]").pos(1, 1, 2), 1, 3)]
2090 #[case(" :", T::t(Token::White, " "), T::t(Token::NameSep, ":").pos(1, 1, 2), 1, 3)]
2091 #[case(" ,", T::t(Token::White, " "), T::t(Token::ValueSep, ",").pos(1, 1, 2), 1, 3)]
2092 #[case(" false", T::t(Token::White, " "), T::t(Token::LitFalse, "false").pos(1, 1, 2), 1, 7)]
2093 #[case(" null", T::t(Token::White, " "), T::t(Token::LitNull, "null").pos(1, 1, 2), 1, 6)]
2094 #[case(" true", T::t(Token::White, " "), T::t(Token::LitTrue, "true").pos(1, 1, 2), 1, 6)]
2095 #[case(" 0", T::t(Token::White, " "), T::t(Token::Num, "0").pos(1, 1, 2), 1, 3)]
2096 #[case(" -0", T::t(Token::White, " "), T::t(Token::Num, "-0").pos(1, 1, 2), 1, 4)]
2097 #[case(r#" """#, T::t(Token::White, " "), T::t(Token::Str, r#""""#).pos(1, 1, 2), 1, 4)]
2098 #[case("\t{", T::t(Token::White, "\t"), T::t(Token::ObjBegin, "{").pos(1, 1, 2), 1, 3)]
2099 #[case(" {", T::t(Token::White, " "), T::t(Token::ObjBegin, "{").pos(2, 1, 3), 1, 4)]
2100 #[case("\n{", T::t(Token::White, "\n"), T::t(Token::ObjBegin, "{").pos(1, 2, 1), 2, 2)]
2101 #[case("\r{", T::t(Token::White, "\r"), T::t(Token::ObjBegin, "{").pos(1, 2, 1), 2, 2)]
2102 #[case("\r\n{", T::t(Token::White, "\r\n"), T::t(Token::ObjBegin, "{").pos(2, 2, 1), 2, 2)]
2103 #[case("\n\r{", T::t(Token::White, "\n\r"), T::t(Token::ObjBegin, "{").pos(2, 3, 1), 3, 2)]
2104 #[case("\n\n{", T::t(Token::White, "\n\n"), T::t(Token::ObjBegin, "{").pos(2, 3, 1), 3, 2)]
2105 #[case("\r\r{", T::t(Token::White, "\r\r"), T::t(Token::ObjBegin, "{").pos(2, 3, 1), 3, 2)]
2106 fn test_analyzer_two_tokens(
2107 #[case] input: &str,
2108 #[case] t1: T,
2109 #[case] t2: T,
2110 #[case] line: usize,
2111 #[case] col: usize,
2112 ) {
2113 {
2115 let mut an = FixedAnalyzer::new(input.as_bytes());
2116 assert_eq!(Pos::default(), *an.pos());
2117
2118 assert_eq!(t1.token, an.next());
2119 assert_eq!(t1.pos, *an.pos());
2120
2121 let content1 = an.content();
2122 assert_eq!(t1.literal, content1.literal());
2123 assert_eq!(t1.is_escaped(), content1.is_escaped());
2124 assert_eq!(t1.unescaped, content1.unescaped());
2125
2126 assert_eq!(t2.token, an.next());
2127 assert_eq!(t2.pos, *an.pos());
2128
2129 let content2 = an.content();
2130 assert_eq!(t2.literal, content2.literal());
2131 assert_eq!(t2.is_escaped(), content2.is_escaped());
2132 assert_eq!(t2.unescaped, content2.unescaped());
2133
2134 assert_eq!(Token::Eof, an.next());
2135 assert_eq!(
2136 Pos {
2137 offset: input.len(),
2138 line,
2139 col
2140 },
2141 *an.pos()
2142 );
2143 }
2144
2145 {
2147 let mut an = FixedAnalyzer::new(input.as_bytes());
2148 assert_eq!(Pos::default(), *an.pos());
2149
2150 assert_eq!(t1.token, an.next());
2151 assert_eq!(t1.pos, *an.pos());
2152
2153 assert_eq!(t2.token, an.next());
2154 assert_eq!(t2.pos, *an.pos());
2155
2156 assert_eq!(Token::Eof, an.next());
2157 assert_eq!(
2158 Pos {
2159 offset: input.len(),
2160 line,
2161 col
2162 },
2163 *an.pos()
2164 );
2165 }
2166 }
2167
2168 #[derive(Debug)]
2169 struct T {
2170 token: Token,
2171 pos: Pos,
2172 literal: &'static str,
2173 unescaped: &'static str,
2174 }
2175
2176 impl T {
2177 fn t(token: Token, literal: &'static str) -> Self {
2178 Self {
2179 token,
2180 pos: Pos::default(),
2181 literal,
2182 unescaped: literal,
2183 }
2184 }
2185
2186 fn pos(mut self, offset: usize, line: usize, col: usize) -> Self {
2187 self.pos = Pos { offset, line, col };
2188 self
2189 }
2190
2191 fn unescaped(mut self, unescaped: &'static str) -> Self {
2192 self.unescaped = unescaped;
2193 self
2194 }
2195
2196 fn is_escaped(&self) -> bool {
2197 self.unescaped != self.literal
2198 }
2199 }
2200
2201 #[rstest]
2202 #[case(r#""\uDC00""#, 0xdc00, None, 3)]
2203 #[case(r#""\udc00""#, 0xdc00, None, 3)]
2204 #[case(r#""\uDFFF""#, 0xdfff, None, 3)]
2205 #[case(r#""\udfff""#, 0xdfff, None, 3)]
2206 #[case(r#""\uD800""#, 0xd800, None, 3)]
2207 #[case(r#""\ud800""#, 0xd800, None, 3)]
2208 #[case(r#""\uDBFF""#, 0xdbff, None, 3)]
2209 #[case(r#""\udbff""#, 0xdbff, None, 3)]
2210 #[case(r#""\uD800x""#, 0xd800, None, 3)]
2211 #[case(r#""\ud800x""#, 0xd800, None, 3)]
2212 #[case(r#""\uDBFFx""#, 0xdbff, None, 3)]
2213 #[case(r#""\udbffx""#, 0xdbff, None, 3)]
2214 #[case(r#""\uD800\""#, 0xd800, None, 3)]
2215 #[case(r#""\ud800\""#, 0xd800, None, 3)]
2216 #[case(r#""\uDBFF\""#, 0xdbff, None, 3)]
2217 #[case(r#""\udbff\""#, 0xdbff, None, 3)]
2218 #[case(r#""\uD800\/""#, 0xd800, None, 3)]
2219 #[case(r#""\ud800\t""#, 0xd800, None, 3)]
2220 #[case(r#""\uDBFF\r""#, 0xdbff, None, 3)]
2221 #[case(r#""\udbff\n""#, 0xdbff, None, 3)]
2222 #[case(r#""\uD800\ud800""#, 0xd800, Some(0xd800), 9)]
2223 #[case(r#""\uD800\uDBFF""#, 0xd800, Some(0xdbff), 9)]
2224 #[case(r#""\udbff\ue000""#, 0xdbff, Some(0xe000), 9)]
2225 #[case(r#""\udbff\u0000""#, 0xdbff, Some(0x0000), 9)]
2226 fn test_analyzer_single_error_bad_surrogate(
2227 #[case] input: &str,
2228 #[case] first: u16,
2229 #[case] second: Option<u16>,
2230 #[case] pos_offset: usize,
2231 ) {
2232 {
2234 let mut an = FixedAnalyzer::new(input.as_bytes());
2235 assert_eq!(Pos::default(), *an.pos());
2236
2237 assert_eq!(Token::Err, an.next());
2238 assert_eq!(Pos::default(), *an.pos());
2239
2240 let err = an.err();
2241 assert_eq!(ErrorKind::BadSurrogate { first, second }, err.kind());
2242 assert_eq!(
2243 Pos {
2244 offset: pos_offset,
2245 line: 1,
2246 col: pos_offset + 1
2247 },
2248 *err.pos()
2249 );
2250
2251 assert_eq!(Token::Err, an.next());
2252 assert_eq!(Pos::default(), *an.pos());
2253 }
2254
2255 {
2257 let mut an = FixedAnalyzer::new(input.as_bytes());
2258 assert_eq!(Pos::default(), *an.pos());
2259
2260 assert_eq!(Token::Err, an.next());
2261 assert_eq!(Pos::default(), *an.pos());
2262
2263 assert_eq!(Token::Err, an.next());
2264 assert_eq!(Pos::default(), *an.pos());
2265 }
2266 }
2267
2268 #[rstest]
2269 #[case(&[0xc2, 0xc0], 1)]
2270 #[case(&[0xdf, 0xd0], 1)]
2271 #[case(&[0xe0, 0x7f, 0x80], 1)]
2272 #[case(&[0xe0, 0x80, 0x80], 1)]
2273 #[case(&[0xe0, 0xc0, 0x80], 1)]
2274 #[case(&[0xed, 0xa0, 0x80], 1)]
2275 #[case(&[0xed, 0xa0, 0xbf], 1)]
2276 #[case(&[0xed, 0xb0, 0x80], 1)]
2277 #[case(&[0xed, 0xb0, 0xbf], 1)]
2278 #[case(&[0xef, 0x7f, 0x80], 1)]
2279 #[case(&[0xef, 0xc0, 0x80], 1)]
2280 #[case(&[0xe0, 0x80, 0x7f], 2)]
2281 #[case(&[0xe0, 0x80, 0xc0], 2)]
2282 #[case(&[0xe0, 0xbf, 0x7f], 2)]
2283 #[case(&[0xe0, 0xbf, 0xc0], 2)]
2284 #[case(&[0xf0, 0x7f, 0x80, 0x80], 1)]
2285 #[case(&[0xf0, 0x80, 0x80, 0x80], 1)]
2286 #[case(&[0xf0, 0xc0, 0x80, 0x80], 1)]
2287 #[case(&[0xf4, 0x7f, 0x80, 0x80], 1)]
2288 #[case(&[0xf4, 0xc0, 0x80, 0x80], 1)]
2289 #[case(&[0xf4, 0x90, 0x80, 0x80], 1)]
2290 #[case(&[0xf0, 0x80, 0x7f, 0x80], 2)]
2291 #[case(&[0xf0, 0x80, 0xc0, 0x80], 2)]
2292 #[case(&[0xf0, 0xbf, 0x7f, 0x80], 2)]
2293 #[case(&[0xf0, 0xbf, 0xc0, 0x80], 2)]
2294 #[case(&[0xf0, 0x80, 0x80, 0x7f], 3)]
2295 #[case(&[0xf0, 0x80, 0x80, 0xc0], 3)]
2296 #[case(&[0xf0, 0xbf, 0xbf, 0x7f], 3)]
2297 #[case(&[0xf0, 0xbf, 0xbf, 0xc0], 3)]
2298 fn test_analyzer_single_error_bad_utf8_cont_byte(#[case] input: &[u8], #[case] offset: u8) {
2299 let mut buf = Vec::with_capacity(input.len() + 1);
2301 buf.push(b'"');
2302 buf.extend_from_slice(input);
2303
2304 {
2306 let mut an = FixedAnalyzer::new(buf.clone());
2307 assert_eq!(Pos::default(), *an.pos());
2308
2309 assert_eq!(Token::Err, an.next());
2310 assert_eq!(Pos::default(), *an.pos());
2311
2312 let err = an.err();
2313 assert_eq!(
2314 ErrorKind::BadUtf8ContByte {
2315 seq_len: input.len() as u8,
2316 offset,
2317 value: input[offset as usize]
2318 },
2319 err.kind()
2320 );
2321 assert_eq!(
2322 Pos {
2323 offset: 1,
2324 line: 1,
2325 col: 2, },
2327 *err.pos()
2328 );
2329
2330 assert_eq!(Token::Err, an.next());
2331 assert_eq!(Pos::default(), *an.pos());
2332 }
2333
2334 {
2336 let mut an = FixedAnalyzer::new(buf.clone());
2337 assert_eq!(Pos::default(), *an.pos());
2338
2339 assert_eq!(Token::Err, an.next());
2340 assert_eq!(Pos::default(), *an.pos());
2341
2342 assert_eq!(Token::Err, an.next());
2343 assert_eq!(Pos::default(), *an.pos());
2344 }
2345 }
2346
2347 #[rstest]
2348 #[case(0x80)]
2352 #[case(0x81)]
2353 #[case(0x82)]
2354 #[case(0x83)]
2355 #[case(0x84)]
2356 #[case(0x85)]
2357 #[case(0x86)]
2358 #[case(0x87)]
2359 #[case(0x88)]
2360 #[case(0x89)]
2361 #[case(0x8a)]
2362 #[case(0x8b)]
2363 #[case(0x8c)]
2364 #[case(0x8d)]
2365 #[case(0x8e)]
2366 #[case(0x8f)]
2367 #[case(0x90)]
2368 #[case(0x91)]
2369 #[case(0x92)]
2370 #[case(0x93)]
2371 #[case(0x94)]
2372 #[case(0x95)]
2373 #[case(0x96)]
2374 #[case(0x97)]
2375 #[case(0x98)]
2376 #[case(0x99)]
2377 #[case(0x9a)]
2378 #[case(0x9b)]
2379 #[case(0x9c)]
2380 #[case(0x9d)]
2381 #[case(0x9e)]
2382 #[case(0x9f)]
2383 #[case(0xa0)]
2384 #[case(0xa1)]
2385 #[case(0xa2)]
2386 #[case(0xa3)]
2387 #[case(0xa4)]
2388 #[case(0xa5)]
2389 #[case(0xa6)]
2390 #[case(0xa7)]
2391 #[case(0xa8)]
2392 #[case(0xa9)]
2393 #[case(0xaa)]
2394 #[case(0xab)]
2395 #[case(0xac)]
2396 #[case(0xad)]
2397 #[case(0xae)]
2398 #[case(0xaf)]
2399 #[case(0xb0)]
2400 #[case(0xb1)]
2401 #[case(0xb2)]
2402 #[case(0xb3)]
2403 #[case(0xb4)]
2404 #[case(0xb5)]
2405 #[case(0xb6)]
2406 #[case(0xb7)]
2407 #[case(0xb8)]
2408 #[case(0xb9)]
2409 #[case(0xba)]
2410 #[case(0xbb)]
2411 #[case(0xbc)]
2412 #[case(0xbd)]
2413 #[case(0xbe)]
2414 #[case(0xbf)]
2415 #[case(0xc0)]
2419 #[case(0xc1)]
2420 #[case(0xf5)]
2424 #[case(0xf6)]
2425 #[case(0xf7)]
2426 #[case(0xf8)]
2427 #[case(0xf9)]
2428 #[case(0xfa)]
2429 #[case(0xfb)]
2430 #[case(0xfc)]
2431 #[case(0xfd)]
2432 #[case(0xfe)]
2433 #[case(0xff)]
2434 fn test_analyzer_single_error_bad_utf8_start_byte(#[case] b: u8) {
2435 let mut buf = Vec::with_capacity(2);
2437 buf.push(b'"');
2438 buf.push(b);
2439
2440 {
2442 let mut an = FixedAnalyzer::new(buf.clone());
2443 assert_eq!(Pos::default(), *an.pos());
2444
2445 assert_eq!(Token::Err, an.next());
2446 assert_eq!(Pos::default(), *an.pos());
2447
2448 let err = an.err();
2449 assert_eq!(
2450 ErrorKind::UnexpectedByte {
2451 token: Some(Token::Str),
2452 expect: Expect::StrChar,
2453 actual: b,
2454 },
2455 err.kind()
2456 );
2457 assert_eq!(
2458 Pos {
2459 offset: 1,
2460 line: 1,
2461 col: 2,
2462 },
2463 *err.pos()
2464 );
2465
2466 assert_eq!(Token::Err, an.next());
2467 assert_eq!(Pos::default(), *an.pos());
2468 }
2469
2470 {
2472 let mut an = FixedAnalyzer::new(buf.clone());
2473 assert_eq!(Pos::default(), *an.pos());
2474
2475 assert_eq!(Token::Err, an.next());
2476 assert_eq!(Pos::default(), *an.pos());
2477
2478 assert_eq!(Token::Err, an.next());
2479 assert_eq!(Pos::default(), *an.pos());
2480 }
2481 }
2482
2483 #[rstest]
2484 #[case("-}", Expect::Digit)]
2488 #[case("-]", Expect::Digit)]
2489 #[case("-a", Expect::Digit)]
2490 #[case("- ", Expect::Digit)]
2491 #[case("00", Expect::DotExpOrBoundary)]
2495 #[case("01", Expect::DotExpOrBoundary)]
2496 #[case("02", Expect::DotExpOrBoundary)]
2497 #[case("03", Expect::DotExpOrBoundary)]
2498 #[case("04", Expect::DotExpOrBoundary)]
2499 #[case("05", Expect::DotExpOrBoundary)]
2500 #[case("06", Expect::DotExpOrBoundary)]
2501 #[case("07", Expect::DotExpOrBoundary)]
2502 #[case("08", Expect::DotExpOrBoundary)]
2503 #[case("09", Expect::DotExpOrBoundary)]
2504 #[case("-00", Expect::DotExpOrBoundary)]
2505 #[case("-01", Expect::DotExpOrBoundary)]
2506 #[case("-02", Expect::DotExpOrBoundary)]
2507 #[case("-03", Expect::DotExpOrBoundary)]
2508 #[case("-04", Expect::DotExpOrBoundary)]
2509 #[case("-05", Expect::DotExpOrBoundary)]
2510 #[case("-06", Expect::DotExpOrBoundary)]
2511 #[case("-07", Expect::DotExpOrBoundary)]
2512 #[case("-08", Expect::DotExpOrBoundary)]
2513 #[case("-09", Expect::DotExpOrBoundary)]
2514 #[case("0x", Expect::DotExpOrBoundary)]
2518 #[case("1x", Expect::DigitDotExpOrBoundary)]
2519 #[case("9/", Expect::DigitDotExpOrBoundary)]
2520 #[case("13456789000a", Expect::DigitDotExpOrBoundary)]
2521 #[case("0E,", Expect::DigitOrExpSign)]
2525 #[case("0e:", Expect::DigitOrExpSign)]
2526 #[case("1E ", Expect::DigitOrExpSign)]
2527 #[case("9ex", Expect::DigitOrExpSign)]
2528 #[case("0.a", Expect::Digit)]
2532 #[case("0.{", Expect::Digit)]
2533 #[case("0.:", Expect::Digit)]
2534 #[case("0.-", Expect::Digit)]
2535 #[case("-0.a", Expect::Digit)]
2536 #[case("-0.{", Expect::Digit)]
2537 #[case("-0.:", Expect::Digit)]
2538 #[case("-0.-", Expect::Digit)]
2539 #[case("1.E", Expect::Digit)]
2540 #[case("2.e", Expect::Digit)]
2541 #[case("3.a", Expect::Digit)]
2542 #[case("4.a", Expect::Digit)]
2543 #[case("5.a", Expect::Digit)]
2544 #[case("6.a", Expect::Digit)]
2545 #[case("7.a", Expect::Digit)]
2546 #[case("8.a", Expect::Digit)]
2547 #[case("9.a", Expect::Digit)]
2548 #[case("-1.E", Expect::Digit)]
2549 #[case("-2.e", Expect::Digit)]
2550 #[case("-3.a", Expect::Digit)]
2551 #[case("-4.a", Expect::Digit)]
2552 #[case("-5.a", Expect::Digit)]
2553 #[case("-6.a", Expect::Digit)]
2554 #[case("-7.a", Expect::Digit)]
2555 #[case("-8.a", Expect::Digit)]
2556 #[case("-9.a", Expect::Digit)]
2557 #[case("10.E", Expect::Digit)]
2558 #[case("20.e", Expect::Digit)]
2559 #[case("30.a", Expect::Digit)]
2560 #[case("40.a", Expect::Digit)]
2561 #[case("50.a", Expect::Digit)]
2562 #[case("60.a", Expect::Digit)]
2563 #[case("70.a", Expect::Digit)]
2564 #[case("80.a", Expect::Digit)]
2565 #[case("90.a", Expect::Digit)]
2566 #[case("-10.E", Expect::Digit)]
2567 #[case("-20.e", Expect::Digit)]
2568 #[case("-30.a", Expect::Digit)]
2569 #[case("-40.a", Expect::Digit)]
2570 #[case("-50.a", Expect::Digit)]
2571 #[case("-60.a", Expect::Digit)]
2572 #[case("-70.a", Expect::Digit)]
2573 #[case("-80.a", Expect::Digit)]
2574 #[case("-90.a", Expect::Digit)]
2575 #[case("0.0|", Expect::DigitExpOrBoundary)]
2579 #[case("-0.0-", Expect::DigitExpOrBoundary)]
2580 #[case("1.0D", Expect::DigitExpOrBoundary)]
2581 #[case("-1.5d", Expect::DigitExpOrBoundary)]
2582 #[case("9.01F", Expect::DigitExpOrBoundary)]
2583 #[case("-9.001f", Expect::DigitExpOrBoundary)]
2584 #[case("100.001x", Expect::DigitExpOrBoundary)]
2585 #[case("0Ee", Expect::DigitOrExpSign)]
2589 #[case("-0e.", Expect::DigitOrExpSign)]
2590 #[case("1Ee", Expect::DigitOrExpSign)]
2591 #[case("-1e.", Expect::DigitOrExpSign)]
2592 #[case("2.0Ef", Expect::DigitOrExpSign)]
2593 #[case("-2.0ef", Expect::DigitOrExpSign)]
2594 #[case("3.01e.", Expect::DigitOrExpSign)]
2595 #[case("-456789.10111213141516171819E\"", Expect::DigitOrExpSign)]
2596 #[case("0E++", Expect::Digit)]
2600 #[case("0e--", Expect::Digit)]
2601 #[case("1E+x", Expect::Digit)]
2602 #[case("2e+\"", Expect::Digit)]
2603 #[case("3E+:", Expect::Digit)]
2604 #[case("4e+,", Expect::Digit)]
2605 #[case("5E+{", Expect::Digit)]
2606 #[case("6e-}", Expect::Digit)]
2607 #[case("7E-[", Expect::Digit)]
2608 #[case("8e-]", Expect::Digit)]
2609 #[case("9E- ", Expect::Digit)]
2610 #[case("-0E+\t", Expect::Digit)]
2611 #[case("-0e-e", Expect::Digit)]
2612 #[case("-1E+E", Expect::Digit)]
2613 #[case("-2e+.", Expect::Digit)]
2614 #[case("-3E+!", Expect::Digit)]
2615 #[case("-4e+@", Expect::Digit)]
2616 #[case("-5E+#", Expect::Digit)]
2617 #[case("-6e-$", Expect::Digit)]
2618 #[case("-7E-%", Expect::Digit)]
2619 #[case("-8e-^", Expect::Digit)]
2620 #[case("-9E-&", Expect::Digit)]
2621 #[case("0.1E++", Expect::Digit)]
2622 #[case("0.1e--", Expect::Digit)]
2623 #[case("1.1E+x", Expect::Digit)]
2624 #[case("2.1e+\"", Expect::Digit)]
2625 #[case("3.1E+:", Expect::Digit)]
2626 #[case("4.1e+,", Expect::Digit)]
2627 #[case("5.1E+{", Expect::Digit)]
2628 #[case("6.1e-}", Expect::Digit)]
2629 #[case("7.1E-[", Expect::Digit)]
2630 #[case("8.1e-]", Expect::Digit)]
2631 #[case("9.1E- ", Expect::Digit)]
2632 #[case("-0.234E+\t", Expect::Digit)]
2633 #[case("-0.234e-e", Expect::Digit)]
2634 #[case("-1.234E+E", Expect::Digit)]
2635 #[case("-2.234e+.", Expect::Digit)]
2636 #[case("-3.234E+!", Expect::Digit)]
2637 #[case("-4.234e+@", Expect::Digit)]
2638 #[case("-5.234E+#", Expect::Digit)]
2639 #[case("-6.234e-$", Expect::Digit)]
2640 #[case("-7.234E-%", Expect::Digit)]
2641 #[case("-8.234e-^", Expect::Digit)]
2642 #[case("-9.234E-&", Expect::Digit)]
2643 #[case("0E0e", Expect::DigitOrBoundary)]
2647 #[case("0E+0e", Expect::DigitOrBoundary)]
2648 #[case("0E-0e", Expect::DigitOrBoundary)]
2649 #[case("0.0e0e", Expect::DigitOrBoundary)]
2650 #[case("0.00e00e", Expect::DigitOrBoundary)]
2651 #[case("1.1E+1e", Expect::DigitOrBoundary)]
2652 #[case("11.11E+11e", Expect::DigitOrBoundary)]
2653 #[case("99.999E-999e", Expect::DigitOrBoundary)]
2654 fn test_analyzer_single_error_bad_number(#[case] input: &str, #[case] expect: Expect) {
2655 let mut an = FixedAnalyzer::new(input.as_bytes());
2656
2657 assert_eq!(Token::Err, an.next());
2658 assert_eq!(Pos::default(), *an.pos());
2659
2660 let err = an.err();
2661 assert_eq!(
2662 ErrorKind::UnexpectedByte {
2663 token: Some(Token::Num),
2664 expect,
2665 actual: *input.as_bytes().last().unwrap(),
2666 },
2667 err.kind(),
2668 "input={input:?}"
2669 );
2670 assert_eq!(
2671 Pos {
2672 offset: input.len() - 1,
2673 line: 1,
2674 col: input.len(),
2675 },
2676 *err.pos(),
2677 "input={input:?}"
2678 );
2679
2680 assert_eq!(Token::Err, an.next(), "input={input:?}");
2681 assert_eq!(Pos::default(), *an.pos(), "input={input:?}");
2682 }
2683
2684 #[rstest]
2685 #[case(r#"\0"#, Expect::EscChar)]
2686 #[case(r#"\a"#, Expect::EscChar)]
2687 #[case(r#"\v"#, Expect::EscChar)]
2688 #[case(r#"\x"#, Expect::EscChar)]
2689 #[case(r#"\uG"#, Expect::UnicodeEscHexDigit)]
2690 #[case(r#"\u:"#, Expect::UnicodeEscHexDigit)]
2691 #[case(r#"\u_"#, Expect::UnicodeEscHexDigit)]
2692 #[case(r#"\u0G"#, Expect::UnicodeEscHexDigit)]
2693 #[case(r#"\u1:"#, Expect::UnicodeEscHexDigit)]
2694 #[case(r#"\u2,"#, Expect::UnicodeEscHexDigit)]
2695 #[case(r#"\u3["#, Expect::UnicodeEscHexDigit)]
2696 #[case(r#"\u4]"#, Expect::UnicodeEscHexDigit)]
2697 #[case(r#"\u5{"#, Expect::UnicodeEscHexDigit)]
2698 #[case(r#"\u6}"#, Expect::UnicodeEscHexDigit)]
2699 #[case(r#"\u7."#, Expect::UnicodeEscHexDigit)]
2700 #[case(r#"\u8""#, Expect::UnicodeEscHexDigit)]
2701 #[case(r#"\u9g"#, Expect::UnicodeEscHexDigit)]
2702 #[case(r#"\uAG"#, Expect::UnicodeEscHexDigit)]
2703 #[case(r#"\ua_"#, Expect::UnicodeEscHexDigit)]
2704 #[case(r#"\uB_"#, Expect::UnicodeEscHexDigit)]
2705 #[case(r#"\ub_"#, Expect::UnicodeEscHexDigit)]
2706 #[case(r#"\uC_"#, Expect::UnicodeEscHexDigit)]
2707 #[case(r#"\uc_"#, Expect::UnicodeEscHexDigit)]
2708 #[case(r#"\uD_"#, Expect::UnicodeEscHexDigit)]
2709 #[case(r#"\ud_"#, Expect::UnicodeEscHexDigit)]
2710 #[case(r#"\uE_"#, Expect::UnicodeEscHexDigit)]
2711 #[case(r#"\ue_"#, Expect::UnicodeEscHexDigit)]
2712 #[case(r#"\uF_"#, Expect::UnicodeEscHexDigit)]
2713 #[case(r#"\uf_"#, Expect::UnicodeEscHexDigit)]
2714 #[case(r#"\u1a_"#, Expect::UnicodeEscHexDigit)]
2715 #[case(r#"\ub2C_"#, Expect::UnicodeEscHexDigit)]
2716 #[case(r#"\ud800\ug"#, Expect::UnicodeEscHexDigit)]
2717 #[case(r#"\ud800\u0:"#, Expect::UnicodeEscHexDigit)]
2718 #[case(r#"\ud800\u00:"#, Expect::UnicodeEscHexDigit)]
2719 #[case(r#"\ud800\u000:"#, Expect::UnicodeEscHexDigit)]
2720 fn test_analyzer_single_error_bad_escape(#[case] input: &str, #[case] expect: Expect) {
2721 let mut s = String::with_capacity(1 + input.len());
2722 s.push('"');
2723 s.push_str(input);
2724
2725 let mut an = FixedAnalyzer::new(s.as_bytes());
2726
2727 assert_eq!(Token::Err, an.next());
2728 assert_eq!(Pos::default(), *an.pos());
2729
2730 let err = an.err();
2731 assert_eq!(
2732 ErrorKind::UnexpectedByte {
2733 token: Some(Token::Str),
2734 expect,
2735 actual: *input.as_bytes().last().unwrap(),
2736 },
2737 err.kind(),
2738 "input={input:?}"
2739 );
2740 assert_eq!(
2741 Pos {
2742 offset: s.len() - 1,
2743 line: 1,
2744 col: s.len(),
2745 },
2746 *err.pos(),
2747 "input={input:?}"
2748 );
2749
2750 assert_eq!(Token::Err, an.next(), "input={input:?}");
2751 assert_eq!(Pos::default(), *an.pos(), "input={input:?}");
2752 }
2753
2754 #[rstest]
2755 #[case::nul(0x00)]
2756 #[case::soh(0x01)]
2757 #[case::stx(0x02)]
2758 #[case::etx(0x03)]
2759 #[case::eot(0x04)]
2760 #[case::enq(0x05)]
2761 #[case::ack(0x06)]
2762 #[case::bel(0x07)]
2763 #[case::bs(0x08)]
2764 #[case::ht(0x09)]
2765 #[case::lf(0x0A)]
2766 #[case::vt(0x0B)]
2767 #[case::ff(0x0C)]
2768 #[case::cr(0x0D)]
2769 #[case::so(0x0E)]
2770 #[case::si(0x0F)]
2771 #[case::dle(0x10)]
2772 #[case::dc1(0x11)]
2773 #[case::dc2(0x12)]
2774 #[case::dc3(0x13)]
2775 #[case::dc4(0x14)]
2776 #[case::nak(0x15)]
2777 #[case::syn(0x16)]
2778 #[case::etb(0x17)]
2779 #[case::can(0x18)]
2780 #[case::em(0x19)]
2781 #[case::sub(0x1A)]
2782 #[case::esc(0x1B)]
2783 #[case::fs(0x1C)]
2784 #[case::gs(0x1D)]
2785 #[case::rs(0x1E)]
2786 #[case::us(0x1F)]
2787 fn test_analyzer_single_error_control_char(#[case] ctrl: u8) {
2788 static PREFIXES: [&str; 6] = ["", "a", r#"\u1234"#, "café", "𝄞", "🧶"];
2789 static COLS: [usize; 6] = [0, 1, 6, 4, 1, 1];
2790 let mut s: String = '"'.into();
2791
2792 for (prefix, cols) in PREFIXES.iter().zip(COLS.iter().copied()) {
2793 s.truncate(1);
2794 s.push_str(prefix);
2795 s.push(ctrl as char);
2796
2797 let mut an = FixedAnalyzer::new(s.as_bytes());
2798
2799 assert_eq!(Token::Err, an.next());
2800 assert_eq!(Pos::default(), *an.pos());
2801
2802 let err = an.err();
2803 assert_eq!(
2804 ErrorKind::UnexpectedByte {
2805 token: Some(Token::Str),
2806 expect: Expect::StrChar,
2807 actual: ctrl,
2808 },
2809 err.kind(),
2810 "s={s:?}"
2811 );
2812 assert_eq!(
2813 Pos {
2814 offset: s.len() - 1,
2815 line: 1,
2816 col: 2 + cols,
2817 },
2818 *err.pos(),
2819 "s={s:?}"
2820 );
2821 }
2822 }
2823
2824 #[rstest]
2825 #[case("f", 'a', Token::LitFalse)]
2826 #[case("fa", 'l', Token::LitFalse)]
2827 #[case("fal", 's', Token::LitFalse)]
2828 #[case("fals", 'e', Token::LitFalse)]
2829 #[case("n", 'u', Token::LitNull)]
2830 #[case("nu", 'l', Token::LitNull)]
2831 #[case("nul", 'l', Token::LitNull)]
2832 #[case("t", 'r', Token::LitTrue)]
2833 #[case("tr", 'u', Token::LitTrue)]
2834 #[case("tru", 'e', Token::LitTrue)]
2835 fn test_analyzer_single_error_expect_char(
2836 #[case] input: &str,
2837 #[case] expect: char,
2838 #[case] expect_token: Token,
2839 ) {
2840 let bad_chars = &[
2841 b'[', b']', b':', b'{', b'}', b',', b'"', b'\\', b'$', b' ', b'\0', b'\t', b'A', b'x',
2842 b'X', b'0', b'9',
2843 ];
2844 let mut buf = Vec::with_capacity(input.len() + 1);
2845 buf.extend_from_slice(input.as_bytes());
2846 buf.push(b'_');
2847
2848 for (i, actual) in bad_chars.into_iter().enumerate() {
2849 buf[input.len()] = *actual;
2850
2851 let mut an = FixedAnalyzer::new(buf.clone());
2852
2853 assert_eq!(Token::Err, an.next());
2854 assert_eq!(Pos::default(), *an.pos());
2855
2856 let err = an.err();
2857 assert_eq!(
2858 ErrorKind::UnexpectedByte {
2859 token: Some(expect_token),
2860 expect: Expect::Char(expect),
2861 actual: *actual,
2862 },
2863 err.kind(),
2864 "input={input:?}, i={i}, actual={actual:02x}"
2865 );
2866 assert_eq!(
2867 Pos {
2868 offset: input.len(),
2869 line: 1,
2870 col: buf.len(),
2871 },
2872 *err.pos(),
2873 "input={input:?}, i={i}, actual={actual:02x}"
2874 );
2875
2876 assert_eq!(
2877 Token::Err,
2878 an.next(),
2879 "input={input:?}, i={i}, actual={actual:02x}"
2880 );
2881 assert_eq!(
2882 Pos::default(),
2883 *an.pos(),
2884 "input={input:?}, i={i}, actual={actual:02x}"
2885 );
2886 }
2887 }
2888
2889 #[rstest]
2890 #[case("falsep", Token::LitFalse)]
2891 #[case("nullE", Token::LitNull)]
2892 #[case("true0", Token::LitTrue)]
2893 fn test_analyzer_single_error_expect_boundary(
2894 #[case] input: &str,
2895 #[case] expect_token: Token,
2896 ) {
2897 let actual = input.as_bytes().last().copied().unwrap();
2898 let mut an = FixedAnalyzer::new(input.as_bytes());
2899
2900 assert_eq!(Token::Err, an.next());
2901 assert_eq!(Pos::default(), *an.pos());
2902
2903 let err = an.err();
2904 assert_eq!(
2905 ErrorKind::UnexpectedByte {
2906 token: Some(expect_token),
2907 expect: Expect::Boundary,
2908 actual,
2909 },
2910 err.kind(),
2911 );
2912 assert_eq!(
2913 Pos {
2914 offset: input.len() - 1,
2915 line: 1,
2916 col: input.len(),
2917 },
2918 *err.pos(),
2919 );
2920 }
2921
2922 #[rstest]
2923 #[case(r#"f"#, Token::LitFalse)]
2924 #[case(r#"fa"#, Token::LitFalse)]
2925 #[case(r#"fal"#, Token::LitFalse)]
2926 #[case(r#"n"#, Token::LitNull)]
2927 #[case(r#"nu"#, Token::LitNull)]
2928 #[case(r#"nul"#, Token::LitNull)]
2929 #[case(r#"-"#, Token::Num)]
2930 #[case(r#"0."#, Token::Num)]
2931 #[case(r#"1."#, Token::Num)]
2932 #[case(r#"2."#, Token::Num)]
2933 #[case(r#"3."#, Token::Num)]
2934 #[case(r#"4."#, Token::Num)]
2935 #[case(r#"5."#, Token::Num)]
2936 #[case(r#"6."#, Token::Num)]
2937 #[case(r#"7."#, Token::Num)]
2938 #[case(r#"8."#, Token::Num)]
2939 #[case(r#"9."#, Token::Num)]
2940 #[case(r#"10."#, Token::Num)]
2941 #[case(r#"0E"#, Token::Num)]
2942 #[case(r#"0E+"#, Token::Num)]
2943 #[case(r#"0E-"#, Token::Num)]
2944 #[case(r#"0e"#, Token::Num)]
2945 #[case(r#"0e+"#, Token::Num)]
2946 #[case(r#"0e-"#, Token::Num)]
2947 #[case(r#"1.0E"#, Token::Num)]
2948 #[case(r#"1.0E+"#, Token::Num)]
2949 #[case(r#"1.0E-"#, Token::Num)]
2950 #[case(r#"1.0e"#, Token::Num)]
2951 #[case(r#"1.0e+"#, Token::Num)]
2952 #[case(r#"1.0e-"#, Token::Num)]
2953 #[case(r#"""#, Token::Str)]
2954 #[case(r#""a"#, Token::Str)]
2955 #[case(r#""\"#, Token::Str)]
2956 #[case(r#""\u"#, Token::Str)]
2957 #[case(r#""\u1"#, Token::Str)]
2958 #[case(r#""\u12"#, Token::Str)]
2959 #[case(r#""\u123"#, Token::Str)]
2960 #[case(r#""\u1234"#, Token::Str)]
2961 #[case(r#""\u1234 foo bar"#, Token::Str)]
2962 #[case(r#"t"#, Token::LitTrue)]
2963 #[case(r#"tr"#, Token::LitTrue)]
2964 #[case(r#"tru"#, Token::LitTrue)]
2965 fn test_analyzer_single_error_unexpected_eof(#[case] input: &str, #[case] expect: Token) {
2966 {
2968 let mut an = FixedAnalyzer::new(input.as_bytes());
2969 assert_eq!(Pos::default(), *an.pos());
2970
2971 assert_eq!(Token::Err, an.next());
2972 assert_eq!(Pos::default(), *an.pos());
2973
2974 let err = an.err();
2975 assert_eq!(
2976 ErrorKind::UnexpectedEof(expect),
2977 err.kind(),
2978 "input = {input:?}, expect = {expect:?}"
2979 );
2980 assert_eq!(
2981 Pos {
2982 offset: input.len(),
2983 line: 1,
2984 col: 1 + input.len(),
2985 },
2986 *err.pos(),
2987 "input = {input:?}, expect = {expect:?}"
2988 );
2989
2990 assert_eq!(Token::Err, an.next());
2991 assert_eq!(Pos::default(), *an.pos());
2992 }
2993
2994 {
2996 let mut an = FixedAnalyzer::new(input.as_bytes());
2997 assert_eq!(Pos::default(), *an.pos());
2998
2999 assert_eq!(Token::Err, an.next());
3000 assert_eq!(Pos::default(), *an.pos());
3001
3002 assert_eq!(Token::Err, an.next());
3003 assert_eq!(Pos::default(), *an.pos());
3004 }
3005 }
3006
3007 #[rstest]
3008 #[case(0x00)]
3009 #[case(0x01)]
3010 #[case(0x02)]
3011 #[case(0x03)]
3012 #[case(0x04)]
3013 #[case(0x05)]
3014 #[case(0x06)]
3015 #[case(0x07)]
3016 #[case(0x08)]
3017 #[case(0x0b)]
3018 #[case(0x0c)]
3019 #[case(0x0e)]
3020 #[case(0x0f)]
3021 #[case(0x10)]
3022 #[case(0x11)]
3023 #[case(0x12)]
3024 #[case(0x13)]
3025 #[case(0x14)]
3026 #[case(0x15)]
3027 #[case(0x16)]
3028 #[case(0x17)]
3029 #[case(0x18)]
3030 #[case(0x19)]
3031 #[case(0x1a)]
3032 #[case(0x1b)]
3033 #[case(0x1c)]
3034 #[case(0x1d)]
3035 #[case(0x1e)]
3036 #[case(0x1f)]
3037 #[case(b'\'')]
3038 #[case(b'+')]
3039 #[case(b'.')]
3040 #[case(b'E')]
3041 #[case(b'\\')]
3042 #[case(b'e')]
3043 #[case(0x7f)]
3044 #[case(0x80)]
3045 #[case(0xbf)]
3046 #[case(0xc0)]
3047 #[case(0xc7)]
3048 #[case(0xcf)]
3049 #[case(0xd0)]
3050 #[case(0xd7)]
3051 #[case(0xdf)]
3052 #[case(0xe0)]
3053 #[case(0xe7)]
3054 #[case(0xef)]
3055 #[case(0xf0)]
3056 #[case(0xf7)]
3057 #[case(0xff)]
3058 fn test_analyzer_error_non_token_start(#[case] bad: u8) {
3059 {
3061 let mut an = FixedAnalyzer::new(vec![bad]);
3062 assert_eq!(Pos::default(), *an.pos());
3063
3064 assert_eq!(Token::Err, an.next());
3065 assert_eq!(Pos::default(), *an.pos());
3066
3067 let err = an.err();
3068 assert_eq!(
3069 ErrorKind::UnexpectedByte {
3070 token: None,
3071 expect: Expect::TokenStartChar,
3072 actual: bad
3073 },
3074 err.kind(),
3075 "bad = {bad:02x}"
3076 );
3077 assert_eq!(Pos::default(), *err.pos(), "bad = {bad:02x}");
3078
3079 assert_eq!(Token::Err, an.next());
3080 assert_eq!(Pos::default(), *an.pos());
3081 }
3082
3083 {
3085 let valid_list = [
3086 "[",
3087 "]",
3088 "false ",
3089 "null ",
3090 "1 ",
3091 "{",
3092 "}",
3093 r#""a""#,
3094 r#""\u0000 foo \\//""#,
3095 "true\t",
3096 ];
3097
3098 for (i, valid) in valid_list.into_iter().enumerate() {
3099 let mut buf: Vec<u8> = Vec::with_capacity(valid.len() + 1);
3100 buf.extend_from_slice(valid.as_bytes());
3101 buf.push(bad);
3102
3103 let mut an = FixedAnalyzer::new(buf);
3104
3105 let token = an.next();
3106 assert!(
3107 !token.is_terminal(),
3108 "valid = {valid:?}, i = {i}, bad = {bad:02x}"
3109 );
3110 if token.is_literal() || token == Token::Num {
3111 assert_eq!(
3112 Token::White,
3113 an.next(),
3114 "valid = {valid:?}, i = {i}, bad = {bad:02x}"
3115 );
3116 }
3117
3118 assert_eq!(Token::Err, an.next());
3119 let err = an.err();
3120 assert_eq!(
3121 ErrorKind::UnexpectedByte {
3122 token: None,
3123 expect: Expect::TokenStartChar,
3124 actual: bad
3125 },
3126 err.kind(),
3127 "valid = {valid:?}, i = {i}, bad = {bad:02x}"
3128 );
3129 assert_eq!(
3130 Pos {
3131 offset: valid.len(),
3132 line: 1,
3133 col: 1 + valid.len(),
3134 },
3135 *err.pos(),
3136 "valid = {valid:?}, i = {i}, bad = {bad:02x}"
3137 );
3138 }
3139 }
3140 }
3141
3142 #[rstest]
3143 #[case(br#"123.456789:a"#)]
3144 #[case(br#"<"#)]
3145 #[case(br#""foo" "bar" "baz"#)]
3146 #[should_panic(
3147 expected = "no content: last `next()` returned `Token::Err` (use `err()` instead)"
3148 )]
3149 fn test_analyzer_panic_no_content(#[case] input: &[u8]) {
3150 let mut an = FixedAnalyzer::new(input);
3151
3152 loop {
3153 if an.next() == Token::Err {
3154 break;
3155 }
3156 }
3157
3158 let _ = an.content();
3159 }
3160
3161 #[test]
3162 fn test_analyzer_smoke() {
3163 const JSON_TEXT: &str = r#"{
3164 "foo":["bar",1,5e-7, false, null ,true, {"baz":"\\\"aââbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb©¢çc\"\\","qux":[{},{},null]}],
3165 "Lorem ipsum dolor sit amet, consectetur adipiscing elit." : "Cras sed ipsum at arcu porta blandit. Nunc eu mauris lacus. Vivamus dignissim tincidunt gravida. Fusce quis neque enim. Sed ac leo neque. Praesent feugiat efficitur eros, quis venenatis urna porttitor condimentum. Mauris finibus dui non vulputate mattis. Nullam scelerisque nibh vel dui egestas luctus. Vestibulum commodo mi ex. In laoreet hendrerit fringilla.\n\nPraesent vel ex sed dolor fermentum lobortis.",
3166 "👋": ["🌎","🌏", "🌏", "こんにちは、世界"],
3167 "abc\u0020123": {{{"inner":[[[-1,-2.0,-3.00e+0,-4E-0,3.141592653589793238462643383279,null]]]}}}
3168}"#;
3169 const EXPECT: &[(Token, Pos, &str, Option<&str>)] = &[
3170 (
3172 Token::ObjBegin,
3173 Pos {
3174 offset: 0,
3175 line: 1,
3176 col: 1,
3177 },
3178 "{",
3179 None,
3180 ),
3181 (
3182 Token::White,
3183 Pos {
3184 offset: 1,
3185 line: 1,
3186 col: 2,
3187 },
3188 "\n ",
3189 None,
3190 ),
3191 (
3193 Token::Str,
3194 Pos {
3195 offset: 4,
3196 line: 2,
3197 col: 3,
3198 },
3199 r#""foo""#,
3200 None,
3201 ),
3202 (
3203 Token::NameSep,
3204 Pos {
3205 offset: 9,
3206 line: 2,
3207 col: 8,
3208 },
3209 ":",
3210 None,
3211 ),
3212 (
3213 Token::ArrBegin,
3214 Pos {
3215 offset: 10,
3216 line: 2,
3217 col: 9,
3218 },
3219 "[",
3220 None,
3221 ),
3222 (
3223 Token::Str,
3224 Pos {
3225 offset: 11,
3226 line: 2,
3227 col: 10,
3228 },
3229 r#""bar""#,
3230 None,
3231 ),
3232 (
3233 Token::ValueSep,
3234 Pos {
3235 offset: 16,
3236 line: 2,
3237 col: 15,
3238 },
3239 ",",
3240 None,
3241 ),
3242 (
3243 Token::Num,
3244 Pos {
3245 offset: 17,
3246 line: 2,
3247 col: 16,
3248 },
3249 "1",
3250 None,
3251 ),
3252 (
3253 Token::ValueSep,
3254 Pos {
3255 offset: 18,
3256 line: 2,
3257 col: 17,
3258 },
3259 ",",
3260 None,
3261 ),
3262 (
3263 Token::Num,
3264 Pos {
3265 offset: 19,
3266 line: 2,
3267 col: 18,
3268 },
3269 "5e-7",
3270 None,
3271 ),
3272 (
3273 Token::ValueSep,
3274 Pos {
3275 offset: 23,
3276 line: 2,
3277 col: 22,
3278 },
3279 ",",
3280 None,
3281 ),
3282 (
3283 Token::White,
3284 Pos {
3285 offset: 24,
3286 line: 2,
3287 col: 23,
3288 },
3289 " ",
3290 None,
3291 ),
3292 (
3293 Token::LitFalse,
3294 Pos {
3295 offset: 25,
3296 line: 2,
3297 col: 24,
3298 },
3299 "false",
3300 None,
3301 ),
3302 (
3303 Token::ValueSep,
3304 Pos {
3305 offset: 30,
3306 line: 2,
3307 col: 29,
3308 },
3309 ",",
3310 None,
3311 ),
3312 (
3313 Token::White,
3314 Pos {
3315 offset: 31,
3316 line: 2,
3317 col: 30,
3318 },
3319 " ",
3320 None,
3321 ),
3322 (
3323 Token::LitNull,
3324 Pos {
3325 offset: 32,
3326 line: 2,
3327 col: 31,
3328 },
3329 "null",
3330 None,
3331 ),
3332 (
3333 Token::White,
3334 Pos {
3335 offset: 36,
3336 line: 2,
3337 col: 35,
3338 },
3339 " ",
3340 None,
3341 ),
3342 (
3343 Token::ValueSep,
3344 Pos {
3345 offset: 38,
3346 line: 2,
3347 col: 37,
3348 },
3349 ",",
3350 None,
3351 ),
3352 (
3353 Token::LitTrue,
3354 Pos {
3355 offset: 39,
3356 line: 2,
3357 col: 38,
3358 },
3359 "true",
3360 None,
3361 ),
3362 (
3363 Token::ValueSep,
3364 Pos {
3365 offset: 43,
3366 line: 2,
3367 col: 42,
3368 },
3369 ",",
3370 None,
3371 ),
3372 (
3373 Token::White,
3374 Pos {
3375 offset: 44,
3376 line: 2,
3377 col: 43,
3378 },
3379 " ",
3380 None,
3381 ),
3382 (
3383 Token::ObjBegin,
3384 Pos {
3385 offset: 45,
3386 line: 2,
3387 col: 44,
3388 },
3389 "{",
3390 None,
3391 ),
3392 (
3393 Token::Str,
3394 Pos {
3395 offset: 46,
3396 line: 2,
3397 col: 45,
3398 },
3399 r#""baz""#,
3400 None,
3401 ),
3402 (
3403 Token::NameSep,
3404 Pos {
3405 offset: 51,
3406 line: 2,
3407 col: 50,
3408 },
3409 ":",
3410 None,
3411 ),
3412 (
3413 Token::Str,
3414 Pos {
3415 offset: 52,
3416 line: 2,
3417 col: 51,
3418 },
3419 r#""\\\"aââbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb©¢çc\"\\""#,
3420 Some(
3421 r#""\"aââbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb©¢çc"\""#,
3422 ),
3423 ),
3424 (
3425 Token::ValueSep,
3426 Pos {
3427 offset: 149,
3428 line: 2,
3429 col: 143,
3430 },
3431 ",",
3432 None,
3433 ),
3434 (
3435 Token::Str,
3436 Pos {
3437 offset: 150,
3438 line: 2,
3439 col: 144,
3440 },
3441 r#""qux""#,
3442 None,
3443 ),
3444 (
3445 Token::NameSep,
3446 Pos {
3447 offset: 155,
3448 line: 2,
3449 col: 149,
3450 },
3451 ":",
3452 None,
3453 ),
3454 (
3455 Token::ArrBegin,
3456 Pos {
3457 offset: 156,
3458 line: 2,
3459 col: 150,
3460 },
3461 "[",
3462 None,
3463 ),
3464 (
3465 Token::ObjBegin,
3466 Pos {
3467 offset: 157,
3468 line: 2,
3469 col: 151,
3470 },
3471 "{",
3472 None,
3473 ),
3474 (
3475 Token::ObjEnd,
3476 Pos {
3477 offset: 158,
3478 line: 2,
3479 col: 152,
3480 },
3481 "}",
3482 None,
3483 ),
3484 (
3485 Token::ValueSep,
3486 Pos {
3487 offset: 159,
3488 line: 2,
3489 col: 153,
3490 },
3491 ",",
3492 None,
3493 ),
3494 (
3495 Token::ObjBegin,
3496 Pos {
3497 offset: 160,
3498 line: 2,
3499 col: 154,
3500 },
3501 "{",
3502 None,
3503 ),
3504 (
3505 Token::ObjEnd,
3506 Pos {
3507 offset: 161,
3508 line: 2,
3509 col: 155,
3510 },
3511 "}",
3512 None,
3513 ),
3514 (
3515 Token::ValueSep,
3516 Pos {
3517 offset: 162,
3518 line: 2,
3519 col: 156,
3520 },
3521 ",",
3522 None,
3523 ),
3524 (
3525 Token::LitNull,
3526 Pos {
3527 offset: 163,
3528 line: 2,
3529 col: 157,
3530 },
3531 "null",
3532 None,
3533 ),
3534 (
3535 Token::ArrEnd,
3536 Pos {
3537 offset: 167,
3538 line: 2,
3539 col: 161,
3540 },
3541 "]",
3542 None,
3543 ),
3544 (
3545 Token::ObjEnd,
3546 Pos {
3547 offset: 168,
3548 line: 2,
3549 col: 162,
3550 },
3551 "}",
3552 None,
3553 ),
3554 (
3555 Token::ArrEnd,
3556 Pos {
3557 offset: 169,
3558 line: 2,
3559 col: 163,
3560 },
3561 "]",
3562 None,
3563 ),
3564 (
3565 Token::ValueSep,
3566 Pos {
3567 offset: 170,
3568 line: 2,
3569 col: 164,
3570 },
3571 ",",
3572 None,
3573 ),
3574 (
3575 Token::White,
3576 Pos {
3577 offset: 171,
3578 line: 2,
3579 col: 165,
3580 },
3581 "\n ",
3582 None,
3583 ),
3584 (
3586 Token::Str,
3587 Pos {
3588 offset: 174,
3589 line: 3,
3590 col: 3,
3591 },
3592 r#""Lorem ipsum dolor sit amet, consectetur adipiscing elit.""#,
3593 None,
3594 ),
3595 (
3596 Token::White,
3597 Pos {
3598 offset: 232,
3599 line: 3,
3600 col: 61,
3601 },
3602 " ",
3603 None,
3604 ),
3605 (
3606 Token::NameSep,
3607 Pos {
3608 offset: 233,
3609 line: 3,
3610 col: 62,
3611 },
3612 ":",
3613 None,
3614 ),
3615 (
3616 Token::White,
3617 Pos {
3618 offset: 234,
3619 line: 3,
3620 col: 63,
3621 },
3622 " ",
3623 None,
3624 ),
3625 (
3626 Token::Str,
3627 Pos {
3628 offset: 235,
3629 line: 3,
3630 col: 64,
3631 },
3632 r#""Cras sed ipsum at arcu porta blandit. Nunc eu mauris lacus. Vivamus dignissim tincidunt gravida. Fusce quis neque enim. Sed ac leo neque. Praesent feugiat efficitur eros, quis venenatis urna porttitor condimentum. Mauris finibus dui non vulputate mattis. Nullam scelerisque nibh vel dui egestas luctus. Vestibulum commodo mi ex. In laoreet hendrerit fringilla.\n\nPraesent vel ex sed dolor fermentum lobortis.""#,
3633 Some(
3634 r#""Cras sed ipsum at arcu porta blandit. Nunc eu mauris lacus. Vivamus dignissim tincidunt gravida. Fusce quis neque enim. Sed ac leo neque. Praesent feugiat efficitur eros, quis venenatis urna porttitor condimentum. Mauris finibus dui non vulputate mattis. Nullam scelerisque nibh vel dui egestas luctus. Vestibulum commodo mi ex. In laoreet hendrerit fringilla.
3635
3636Praesent vel ex sed dolor fermentum lobortis.""#,
3637 ),
3638 ),
3639 (
3640 Token::ValueSep,
3641 Pos {
3642 offset: 646,
3643 line: 3,
3644 col: 475,
3645 },
3646 ",",
3647 None,
3648 ),
3649 (
3650 Token::White,
3651 Pos {
3652 offset: 647,
3653 line: 3,
3654 col: 476,
3655 },
3656 "\n ",
3657 None,
3658 ),
3659 (
3661 Token::Str,
3662 Pos {
3663 offset: 650,
3664 line: 4,
3665 col: 3,
3666 },
3667 r#""👋""#,
3668 None,
3669 ),
3670 (
3671 Token::NameSep,
3672 Pos {
3673 offset: 656,
3674 line: 4,
3675 col: 6,
3676 },
3677 ":",
3678 None,
3679 ),
3680 (
3681 Token::White,
3682 Pos {
3683 offset: 657,
3684 line: 4,
3685 col: 7,
3686 },
3687 " ",
3688 None,
3689 ),
3690 (
3691 Token::ArrBegin,
3692 Pos {
3693 offset: 660,
3694 line: 4,
3695 col: 10,
3696 },
3697 "[",
3698 None,
3699 ),
3700 (
3701 Token::Str,
3702 Pos {
3703 offset: 661,
3704 line: 4,
3705 col: 11,
3706 },
3707 r#""🌎""#,
3708 None,
3709 ),
3710 (
3711 Token::ValueSep,
3712 Pos {
3713 offset: 667,
3714 line: 4,
3715 col: 14,
3716 },
3717 ",",
3718 None,
3719 ),
3720 (
3721 Token::Str,
3722 Pos {
3723 offset: 668,
3724 line: 4,
3725 col: 15,
3726 },
3727 r#""🌏""#,
3728 None,
3729 ),
3730 (
3731 Token::ValueSep,
3732 Pos {
3733 offset: 674,
3734 line: 4,
3735 col: 18,
3736 },
3737 ",",
3738 None,
3739 ),
3740 (
3741 Token::White,
3742 Pos {
3743 offset: 675,
3744 line: 4,
3745 col: 19,
3746 },
3747 " ",
3748 None,
3749 ),
3750 (
3751 Token::Str,
3752 Pos {
3753 offset: 676,
3754 line: 4,
3755 col: 20,
3756 },
3757 r#""🌏""#,
3758 None,
3759 ),
3760 (
3761 Token::ValueSep,
3762 Pos {
3763 offset: 682,
3764 line: 4,
3765 col: 23,
3766 },
3767 ",",
3768 None,
3769 ),
3770 (
3771 Token::White,
3772 Pos {
3773 offset: 683,
3774 line: 4,
3775 col: 24,
3776 },
3777 " ",
3778 None,
3779 ),
3780 (
3781 Token::Str,
3782 Pos {
3783 offset: 684,
3784 line: 4,
3785 col: 25,
3786 },
3787 r#""こんにちは、世界""#,
3788 None,
3789 ),
3790 (
3791 Token::ArrEnd,
3792 Pos {
3793 offset: 710,
3794 line: 4,
3795 col: 35,
3796 },
3797 "]",
3798 None,
3799 ),
3800 (
3801 Token::ValueSep,
3802 Pos {
3803 offset: 711,
3804 line: 4,
3805 col: 36,
3806 },
3807 ",",
3808 None,
3809 ),
3810 (
3811 Token::White,
3812 Pos {
3813 offset: 712,
3814 line: 4,
3815 col: 37,
3816 },
3817 "\n ",
3818 None,
3819 ),
3820 (
3822 Token::Str,
3823 Pos {
3824 offset: 715,
3825 line: 5,
3826 col: 3,
3827 },
3828 r#""abc\u0020123""#,
3829 Some(r#""abc 123""#),
3830 ),
3831 (
3832 Token::NameSep,
3833 Pos {
3834 offset: 729,
3835 line: 5,
3836 col: 17,
3837 },
3838 ":",
3839 None,
3840 ),
3841 (
3842 Token::White,
3843 Pos {
3844 offset: 730,
3845 line: 5,
3846 col: 18,
3847 },
3848 " ",
3849 None,
3850 ),
3851 (
3852 Token::ObjBegin,
3853 Pos {
3854 offset: 731,
3855 line: 5,
3856 col: 19,
3857 },
3858 "{",
3859 None,
3860 ),
3861 (
3862 Token::ObjBegin,
3863 Pos {
3864 offset: 732,
3865 line: 5,
3866 col: 20,
3867 },
3868 "{",
3869 None,
3870 ),
3871 (
3872 Token::ObjBegin,
3873 Pos {
3874 offset: 733,
3875 line: 5,
3876 col: 21,
3877 },
3878 "{",
3879 None,
3880 ),
3881 (
3882 Token::Str,
3883 Pos {
3884 offset: 734,
3885 line: 5,
3886 col: 22,
3887 },
3888 r#""inner""#,
3889 None,
3890 ),
3891 (
3892 Token::NameSep,
3893 Pos {
3894 offset: 741,
3895 line: 5,
3896 col: 29,
3897 },
3898 ":",
3899 None,
3900 ),
3901 (
3902 Token::ArrBegin,
3903 Pos {
3904 offset: 742,
3905 line: 5,
3906 col: 30,
3907 },
3908 "[",
3909 None,
3910 ),
3911 (
3912 Token::ArrBegin,
3913 Pos {
3914 offset: 743,
3915 line: 5,
3916 col: 31,
3917 },
3918 "[",
3919 None,
3920 ),
3921 (
3922 Token::ArrBegin,
3923 Pos {
3924 offset: 744,
3925 line: 5,
3926 col: 32,
3927 },
3928 "[",
3929 None,
3930 ),
3931 (
3932 Token::Num,
3933 Pos {
3934 offset: 745,
3935 line: 5,
3936 col: 33,
3937 },
3938 "-1",
3939 None,
3940 ),
3941 (
3942 Token::ValueSep,
3943 Pos {
3944 offset: 747,
3945 line: 5,
3946 col: 35,
3947 },
3948 ",",
3949 None,
3950 ),
3951 (
3952 Token::Num,
3953 Pos {
3954 offset: 748,
3955 line: 5,
3956 col: 36,
3957 },
3958 "-2.0",
3959 None,
3960 ),
3961 (
3962 Token::ValueSep,
3963 Pos {
3964 offset: 752,
3965 line: 5,
3966 col: 40,
3967 },
3968 ",",
3969 None,
3970 ),
3971 (
3972 Token::Num,
3973 Pos {
3974 offset: 753,
3975 line: 5,
3976 col: 41,
3977 },
3978 "-3.00e+0",
3979 None,
3980 ),
3981 (
3982 Token::ValueSep,
3983 Pos {
3984 offset: 761,
3985 line: 5,
3986 col: 49,
3987 },
3988 ",",
3989 None,
3990 ),
3991 (
3992 Token::Num,
3993 Pos {
3994 offset: 762,
3995 line: 5,
3996 col: 50,
3997 },
3998 "-4E-0",
3999 None,
4000 ),
4001 (
4002 Token::ValueSep,
4003 Pos {
4004 offset: 767,
4005 line: 5,
4006 col: 55,
4007 },
4008 ",",
4009 None,
4010 ),
4011 (
4012 Token::Num,
4013 Pos {
4014 offset: 768,
4015 line: 5,
4016 col: 56,
4017 },
4018 "3.141592653589793238462643383279",
4019 None,
4020 ),
4021 (
4022 Token::ValueSep,
4023 Pos {
4024 offset: 800,
4025 line: 5,
4026 col: 88,
4027 },
4028 ",",
4029 None,
4030 ),
4031 (
4032 Token::LitNull,
4033 Pos {
4034 offset: 801,
4035 line: 5,
4036 col: 89,
4037 },
4038 "null",
4039 None,
4040 ),
4041 (
4042 Token::ArrEnd,
4043 Pos {
4044 offset: 805,
4045 line: 5,
4046 col: 93,
4047 },
4048 "]",
4049 None,
4050 ),
4051 (
4052 Token::ArrEnd,
4053 Pos {
4054 offset: 806,
4055 line: 5,
4056 col: 94,
4057 },
4058 "]",
4059 None,
4060 ),
4061 (
4062 Token::ArrEnd,
4063 Pos {
4064 offset: 807,
4065 line: 5,
4066 col: 95,
4067 },
4068 "]",
4069 None,
4070 ),
4071 (
4072 Token::ObjEnd,
4073 Pos {
4074 offset: 808,
4075 line: 5,
4076 col: 96,
4077 },
4078 "}",
4079 None,
4080 ),
4081 (
4082 Token::ObjEnd,
4083 Pos {
4084 offset: 809,
4085 line: 5,
4086 col: 97,
4087 },
4088 "}",
4089 None,
4090 ),
4091 (
4092 Token::ObjEnd,
4093 Pos {
4094 offset: 810,
4095 line: 5,
4096 col: 98,
4097 },
4098 "}",
4099 None,
4100 ),
4101 (
4102 Token::White,
4103 Pos {
4104 offset: 811,
4105 line: 5,
4106 col: 99,
4107 },
4108 "\n",
4109 None,
4110 ),
4111 (
4113 Token::ObjEnd,
4114 Pos {
4115 offset: 812,
4116 line: 6,
4117 col: 1,
4118 },
4119 "}",
4120 None,
4121 ),
4122 (
4123 Token::Eof,
4124 Pos {
4125 offset: 813,
4126 line: 6,
4127 col: 2,
4128 },
4129 "",
4130 None,
4131 ),
4132 (
4133 Token::Eof,
4134 Pos {
4135 offset: 813,
4136 line: 6,
4137 col: 2,
4138 },
4139 "",
4140 None,
4141 ),
4142 (
4143 Token::Eof,
4144 Pos {
4145 offset: 813,
4146 line: 6,
4147 col: 2,
4148 },
4149 "",
4150 None,
4151 ),
4152 ];
4153
4154 let mut an = FixedAnalyzer::new(JSON_TEXT.as_bytes());
4155
4156 for (i, (expect_token, expect_pos, expect_literal, expect_unescaped)) in
4157 EXPECT.iter().enumerate()
4158 {
4159 let actual_token = an.next();
4160 let actual_pos = *an.pos();
4161 let content = an.content();
4162
4163 assert_eq!(
4164 *expect_token, actual_token,
4165 "i = {i}, actual_pos = {actual_pos}, expect_pos = {expect_pos}"
4166 );
4167 assert_eq!(
4168 *expect_pos, actual_pos,
4169 "i = {i}, token = {actual_token}, content = {content}"
4170 );
4171 assert_eq!(
4172 *expect_literal,
4173 content.literal(),
4174 "i = {i}, token = {actual_token}"
4175 );
4176 if let Some(u) = expect_unescaped {
4177 assert!(
4178 content.is_escaped(),
4179 "i = {i}, token = {actual_token}, literal = {expect_literal:?}"
4180 );
4181 assert_eq!(*u, content.unescaped());
4182 } else {
4183 assert!(
4184 !content.is_escaped(),
4185 "i = {i}, token = {actual_token}, literal = {expect_literal:?}"
4186 );
4187 assert_eq!(*expect_literal, content.unescaped());
4188 }
4189 }
4190 }
4191
4192 fn inline_buf<const N: usize>(src: &[u8; N]) -> (u8, InlineBuf) {
4193 assert!(N <= INLINE_LEN);
4194 let mut dst = [0; INLINE_LEN];
4195 dst[0..N].copy_from_slice(src);
4196
4197 (u8::try_from(N).unwrap(), dst)
4198 }
4199
4200 impl From<(u8, InlineBuf)> for InnerContent<Vec<u8>> {
4201 fn from(value: (u8, InlineBuf)) -> Self {
4202 InnerContent::Inline(value.0, value.1)
4203 }
4204 }
4205}