1use crate::blocking::io::BlockingRead;
2use core::str::FromStr;
3use crate::shared::*;
4
5pub struct JsonReader<'a, B: AsMut<[u8]>, R: BlockingRead> {
61 inner: ReaderInner<B, R::Error>,
62 reader: &'a mut R,
63}
64
65#[cfg(feature = "std")]
66impl<'a, R: BlockingRead> JsonReader<'a, Vec<u8>, R> {
67 pub fn new(buf_size: usize, reader: &'a mut R) -> Self {
69 let buf = vec![0u8; buf_size];
70 Self::new_with_provided_buffer(buf, reader, false)
71 }
72
73 pub fn new_with_lenient_comma_handling(buf_size: usize, reader: &'a mut R) -> Self {
76 let buf = vec![0u8; buf_size];
77 Self::new_with_provided_buffer(buf, reader, true)
78 }
79}
80
81impl<'a, B: AsMut<[u8]>, R: BlockingRead> JsonReader<'a, B, R> {
82 pub fn new_with_provided_buffer(buf: B, reader: &'a mut R, lenient_comma_handling: bool) -> Self {
85 Self {
86 inner: ReaderInner::new(buf, lenient_comma_handling),
87 reader,
88 }
89 }
90
91 pub fn next(&mut self) -> JsonParseResult<JsonReadToken<'_>, R::Error> {
97 self.consume_whitespace()?;
98
99 match self.read_next_byte()? {
100 None => {
101 Ok(JsonReadToken::EndOfStream)
102 },
103 Some(b',') => {
104 self.inner.on_comma()?;
105 self.next()
106 }
107 Some(b'{') => {
108 self.inner.ensure_accept_value()?;
109 self.inner.state = ReaderState::Initial;
110 Ok(JsonReadToken::StartObject)
111 },
112 Some(b'}') => {
113 self.inner.ensure_accept_end_nested()?;
114 self.inner.state = ReaderState::AfterValue;
115 Ok(JsonReadToken::EndObject)
116 },
117 Some(b'[') => {
118 self.inner.ensure_accept_value()?;
119 self.inner.state = ReaderState::Initial;
120 Ok(JsonReadToken::StartArray)
121 },
122 Some(b']') => {
123 self.inner.ensure_accept_end_nested()?;
124 self.inner.state = ReaderState::AfterValue;
125 Ok(JsonReadToken::EndArray)
126 },
127
128 Some(b'n') => {
129 self.inner.state_change_for_value()?;
130 self.consume_null_literal()
131 },
132 Some(b't') => {
133 self.inner.state_change_for_value()?;
134 self.consume_true_literal()
135 },
136 Some(b'f') => {
137 self.inner.state_change_for_value()?;
138 self.consume_false_literal()
139 },
140
141 Some(b'"') => self.parse_after_quote(), Some(b) => {
143 self.inner.state_change_for_value()?;
144 match b {
145 b'-' | b'0'..=b'9' => self.parse_number_literal(b),
146 _ => self.inner.parse_err("invalid JSON literal")
147 }
148 },
149 }
150 }
151
152 pub fn expect_next_key(&mut self) -> JsonParseResult<Option<&str>, R::Error> {
156 let location = self.location();
157 let next = self.next()?;
158 match next {
159 JsonReadToken::Key(key) => Ok(Some(key)),
160 JsonReadToken::EndObject => Ok(None),
161 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
162 }
163 }
164
165 pub fn expect_next_raw_number(&mut self) -> JsonParseResult<JsonNumber<'_>, R::Error> {
169 let location = self.location();
170 let next = self.next()?;
171 match next {
172 JsonReadToken::NumberLiteral(n) => Ok(n),
173 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
174 }
175 }
176
177 pub fn expect_next_opt_raw_number(&mut self) -> JsonParseResult<Option<JsonNumber<'_>>, R::Error> {
180 let location = self.location();
181 let next = self.next()?;
182 match next {
183 JsonReadToken::NullLiteral => Ok(None),
184 JsonReadToken::NumberLiteral(n) => Ok(Some(n)),
185 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
186 }
187 }
188
189 pub fn expect_next_number<T: FromStr>(&mut self) -> JsonParseResult<T, R::Error> {
216 let n = self.expect_next_raw_number()?;
217 match n.parse::<T>() {
218 Ok(n) => Ok(n),
219 Err(_) => self.inner.parse_err("invalid number"),
220 }
221 }
222
223 pub fn expect_next_opt_number<T: FromStr>(&mut self) -> JsonParseResult<Option<T>, R::Error> {
226 match self.expect_next_opt_raw_number() {
227 Ok(Some(n)) => {
228 match n.parse::<T>() {
229 Ok(n) => Ok(Some(n)),
230 Err(_) => self.inner.parse_err("invalid number"),
231 }
232 }
233 Ok(None) => Ok(None),
234 Err(err) => Err(err),
235 }
236 }
237
238 pub fn expect_next_string(&mut self) -> JsonParseResult<&str, R::Error> {
240 let location = self.location();
241 let next = self.next()?;
242 match next {
243 JsonReadToken::StringLiteral(s) => Ok(s),
244 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
245 }
246 }
247
248 pub fn expect_next_opt_string(&mut self) -> JsonParseResult<Option<&str>, R::Error> {
251 let location = self.location();
252 let next = self.next()?;
253 match next {
254 JsonReadToken::NullLiteral => Ok(None),
255 JsonReadToken::StringLiteral(s) => Ok(Some(s)),
256 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
257 }
258 }
259
260 pub fn expect_next_bool(&mut self) -> JsonParseResult<bool, R::Error> {
263 let location = self.location();
264 let next = self.next()?;
265 match next {
266 JsonReadToken::BooleanLiteral(b) => Ok(b),
267 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
268 }
269 }
270
271 pub fn expect_next_opt_bool(&mut self) -> JsonParseResult<Option<bool>, R::Error> {
274 let location = self.location();
275 let next = self.next()?;
276 match next {
277 JsonReadToken::NullLiteral => Ok(None),
278 JsonReadToken::BooleanLiteral(b) => Ok(Some(b)),
279 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
280 }
281 }
282
283 pub fn expect_next_start_object(&mut self) -> JsonParseResult<(), R::Error> {
285 let location = self.location();
286 let next = self.next()?;
287 match next {
288 JsonReadToken::StartObject => Ok(()),
289 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
290 }
291 }
292
293 pub fn expect_next_opt_start_object(&mut self) -> JsonParseResult<Option<()>, R::Error> {
296 let location = self.location();
297 let next = self.next()?;
298 match next {
299 JsonReadToken::NullLiteral => Ok(None),
300 JsonReadToken::StartObject => Ok(Some(())),
301 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
302 }
303 }
304
305 pub fn expect_next_start_array(&mut self) -> JsonParseResult<(), R::Error> {
307 let location = self.location();
308 let next = self.next()?;
309 match next {
310 JsonReadToken::StartArray => Ok(()),
311 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
312 }
313 }
314
315 pub fn expect_next_opt_start_array(&mut self) -> JsonParseResult<Option<()>, R::Error> {
318 let location = self.location();
319 let next = self.next()?;
320 match next {
321 JsonReadToken::NullLiteral => Ok(None),
322 JsonReadToken::StartArray => Ok(Some(())),
323 other => Err(JsonParseError::UnexpectedToken(other.kind(), location)),
324 }
325 }
326
327 pub fn skip_to_end_of_current_scope(&mut self) -> JsonParseResult<(), R::Error> {
333 let mut nesting_level = 1;
334 loop {
335 match self.next()? {
336 JsonReadToken::StartObject | JsonReadToken::StartArray => {
337 nesting_level += 1;
338 }
339 JsonReadToken::EndObject | JsonReadToken::EndArray=> {
340 nesting_level -= 1;
341 if nesting_level == 0 {
342 break;
343 }
344 }
345 JsonReadToken::EndOfStream => {
346 return Err(JsonParseError::UnexpectedToken(JsonReadToken::EndOfStream.kind(), self.location()));
347 }
348 _ => {
349 continue;
350 }
351 }
352 }
353 Ok(())
354 }
355
356 pub fn skip_value(&mut self) -> JsonParseResult<(), R::Error> {
364 match self.next()? {
365 JsonReadToken::Key(_) |
366 JsonReadToken::EndObject |
367 JsonReadToken::EndArray |
368 JsonReadToken::EndOfStream => {
369 Err(JsonParseError::UnexpectedToken(JsonReadToken::EndOfStream.kind(), self.location()))
370 }
371 JsonReadToken::StartObject |
372 JsonReadToken::StartArray => {
373 self.skip_to_end_of_current_scope()
374 }
375 JsonReadToken::StringLiteral(_) |
376 JsonReadToken::NumberLiteral(_) |
377 JsonReadToken::BooleanLiteral(_) |
378 JsonReadToken::NullLiteral => {
379 Ok(())
380 }
381 }
382 }
383
384 fn consume_whitespace(&mut self) -> JsonParseResult<(), R::Error> {
385 while let Some(next) = self.read_next_byte()? {
386 match next {
387 b' ' | b'\t' | b'\n' | b'\r' => {
388 }
389 next => {
390 self.inner.parked_next = Some(next);
391 break;
392 }
393 }
394 }
395 Ok(())
396 }
397
398 fn read_next_byte(&mut self) -> JsonParseResult<Option<u8>, R::Error> {
399 if let Some(parked) = self.inner.parked_next.take() {
401 return Ok(Some(parked));
402 }
403
404 if let Some(byte) =self.reader.read()? {
405 self.inner.cur_location.after_byte(byte);
406 Ok(Some(byte))
407 }
408 else {
409 Ok(None)
410 }
411 }
412
413 fn consume_null_literal(&mut self) -> JsonParseResult<JsonReadToken<'_>, R::Error> {
414 if self.read_next_byte()? != Some(b'u') {
415 return self.inner.parse_err("incomplete null literal");
416 }
417 if self.read_next_byte()? != Some(b'l') {
418 return self.inner.parse_err("incomplete null literal");
419 }
420 if self.read_next_byte()? != Some(b'l') {
421 return self.inner.parse_err("incomplete null literal");
422 }
423 Ok(JsonReadToken::NullLiteral)
424 }
425
426 fn consume_true_literal(&mut self) -> JsonParseResult<JsonReadToken<'_>, R::Error> {
427 if self.read_next_byte()? != Some(b'r') {
428 return self.inner.parse_err("incomplete true literal");
429 }
430 if self.read_next_byte()? != Some(b'u') {
431 return self.inner.parse_err("incomplete true literal");
432 }
433 if self.read_next_byte()? != Some(b'e') {
434 return self.inner.parse_err("incomplete true literal");
435 }
436 Ok(JsonReadToken::BooleanLiteral(true))
437 }
438
439 fn consume_false_literal(&mut self) -> JsonParseResult<JsonReadToken<'_>, R::Error> {
440 if self.read_next_byte()? != Some(b'a') {
441 return self.inner.parse_err("incomplete false literal");
442 }
443 if self.read_next_byte()? != Some(b'l') {
444 return self.inner.parse_err("incomplete false literal");
445 }
446 if self.read_next_byte()? != Some(b's') {
447 return self.inner.parse_err("incomplete false literal");
448 }
449 if self.read_next_byte()? != Some(b'e') {
450 return self.inner.parse_err("incomplete false literal");
451 }
452 Ok(JsonReadToken::BooleanLiteral(false))
453 }
454
455 fn parse_after_quote(&mut self) -> JsonParseResult<JsonReadToken<'_>, R::Error> {
456 self.inner.ind_end_buf = 0;
457
458 loop {
459 if let Some(next) = self.read_next_byte()? {
460 match next {
461 b'"' => break,
462 b'\\' => {
463 match self.read_next_byte()? {
464 Some(b'"') => self.inner.append_to_buf(b'"')?,
465 Some(b'\\') => self.inner.append_to_buf(b'\\')?,
466 Some(b'/') => self.inner.append_to_buf(b'/')?,
467 Some(b'b') => self.inner.append_to_buf(0x08)?,
468 Some(b'f') => self.inner.append_to_buf(0x0c)?,
469 Some(b'n') => self.inner.append_to_buf(b'\n')?,
470 Some(b'r') => self.inner.append_to_buf(b'\r')?,
471 Some(b't') => self.inner.append_to_buf(b'\t')?,
472 Some(b'u') => {
473 let cp = self.parse_unicode_codepoint()?;
474 self.inner.append_code_point(cp)?;
475 },
476 _ => return self.inner.parse_err("invalid escape in string literal"),
477 }
478 },
479 ch => {
480 self.inner.append_to_buf(ch)?;
481 }
482 }
483 }
484 else {
485 return self.inner.parse_err("unterminated string literal");
486 }
487 }
488
489 self.consume_whitespace()?;
493 match self.read_next_byte()? {
494 Some(b':') => {
495 match self.inner.state {
496 ReaderState::Initial |
497 ReaderState::BeforeEntry => {
498 self.inner.state = ReaderState::AfterKey;
499 }
500 ReaderState::AfterKey => {
501 return self.inner.parse_err("two keys without value");
502 }
503 ReaderState::AfterValue => {
504 return self.inner.parse_err("missing comma");
505 }
506 }
507 Ok(JsonReadToken::Key(self.inner.buf_as_str()?))
508 },
509 other => {
510 self.inner.state_change_for_value()?;
511 self.inner.parked_next = other;
512 Ok(JsonReadToken::StringLiteral(self.inner.buf_as_str()?))
513 }
514 }
515 }
516
517 fn parse_unicode_codepoint(&mut self) -> JsonParseResult<u16, R::Error> {
518 let mut cp: u16 = 0;
520 for _ in 0..4 {
521 if let Some(b) = self.read_next_byte()? {
522 cp = cp << 4;
523 match b {
524 b'0'..=b'9' => cp += (b - b'0') as u16,
525 b'a'..=b'f' => cp += (b - b'a' + 10) as u16,
526 b'A'..=b'Z' => cp += (b - b'A' + 10) as u16,
527 _ => {
528 return self.inner.parse_err("not a four-digit hex number after \\u");
529 }
530 }
531 }
532 else {
533 return self.inner.parse_err("incomplete UTF codepoint in string literal");
534 }
535 }
536 Ok(cp)
537 }
538
539 fn parse_number_literal(&mut self, b: u8) -> JsonParseResult<JsonReadToken<'_>, R::Error> {
540 self.inner.buf.as_mut()[0] = b;
541 self.inner.ind_end_buf = 1;
542
543 while let Some(next) = self.read_next_byte()? {
544 match next {
545 b'0'..=b'9' |
546 b'+' | b'-' | b'e' | b'E' |
547 b'.' => {
548 self.inner.append_to_buf(next)?;
549 }
550 other => {
551 self.inner.parked_next = Some(other);
552 break;
553 }
554 }
555 }
556 Ok(JsonReadToken::NumberLiteral(JsonNumber(self.inner.buf_as_str().unwrap())))
557 }
558
559 #[inline]
561 pub fn location(&self) -> Location {
562 self.inner.cur_location
563 }
564}
565
566#[cfg(test)]
567mod tests {
568 use std::io;
569 use super::*;
570 use rstest::*;
571 use std::io::{Cursor, Read};
572
573 fn assert_is_similar_error(actual: &JsonParseError<std::io::Error>, expected: &JsonParseError<std::io::Error>) {
574 match actual {
575 JsonParseError::Io(self_e) => {
576 if let JsonParseError::Io(other_e) = expected {
577 assert_eq!(self_e.kind(), other_e.kind());
578 return;
579 }
580 }
581 JsonParseError::Utf8(_) => {
582 if let JsonParseError::Utf8(_) = expected {
583 return;
584 }
585 }
586 JsonParseError::Parse(msg, _) => {
587 if let JsonParseError::Parse(other_msg, _) = expected {
588 assert_eq!(msg, other_msg);
589 return;
590 }
591 }
592 JsonParseError::UnexpectedToken(_,_) => {
593 if let JsonParseError::UnexpectedToken(_,_) = expected {
594 return;
595 }
596 }
597 JsonParseError::BufferOverflow(_) => {
598 if let JsonParseError::BufferOverflow(_) = expected {
599 return;
600 }
601 }
602 }
603
604 panic!("{:?} != {:?}", actual, expected);
605 }
606
607 #[rstest]
608 #[case::empty("", vec![], None)]
609 #[case::empty_repeated_end_of_stream("", vec![JsonReadToken::EndOfStream, JsonReadToken::EndOfStream, JsonReadToken::EndOfStream, ], None)]
610
611 #[case::null_literal("null", vec![JsonReadToken::NullLiteral], None)]
612 #[case::true_literal("true", vec![JsonReadToken::BooleanLiteral(true)], None)]
613 #[case::false_literal("false", vec![JsonReadToken::BooleanLiteral(false)], None)]
614 #[case::start_object("{", vec![JsonReadToken::StartObject], None)]
615 #[case::end_object("{}", vec![JsonReadToken::StartObject, JsonReadToken::EndObject], None)]
616 #[case::start_array("[", vec![JsonReadToken::StartArray], None)]
617 #[case::end_array("[]", vec![JsonReadToken::StartArray, JsonReadToken::EndArray], None)]
618
619 #[case::key("\"xyz\":", vec![JsonReadToken::Key("xyz")], None)]
620 #[case::key_with_escapes("\"x\\ry\\nz\":", vec![JsonReadToken::Key("x\ry\nz")], None)]
621 #[case::key_ws("\"xyz\" \n:", vec![JsonReadToken::Key("xyz")], None)]
622 #[case::key_value("\"xyz\" \n:\r\tfalse", vec![JsonReadToken::Key("xyz"), JsonReadToken::BooleanLiteral(false)], None)]
623
624 #[case::string_literal(r#""abc""#, vec![JsonReadToken::StringLiteral("abc")], None)]
625 #[case::string_literal_empty(r#""""#, vec![JsonReadToken::StringLiteral("")], None)]
626 #[case::string_literal_quot(r#""\"""#, vec![JsonReadToken::StringLiteral("\"")], None)]
627 #[case::string_literal_backslash(r#""\\""#, vec![JsonReadToken::StringLiteral("\\")], None)]
628 #[case::string_literal_slash(r#""\/""#, vec![JsonReadToken::StringLiteral("/")], None)]
629 #[case::string_literal_backslash(r#""\b""#, vec![JsonReadToken::StringLiteral("\x08")], None)]
630 #[case::string_literal_formfeed(r#""\f""#, vec![JsonReadToken::StringLiteral("\x0c")], None)]
631 #[case::string_literal_linefeed(r#""\n""#, vec![JsonReadToken::StringLiteral("\n")], None)]
632 #[case::string_literal_carriage_return(r#""\r""#, vec![JsonReadToken::StringLiteral("\r")], None)]
633 #[case::string_literal_tab(r#""\t""#, vec![JsonReadToken::StringLiteral("\t")], None)]
634 #[case::string_literal_unicode_y(r#""\u0079""#, vec![JsonReadToken::StringLiteral("y")], None)]
635 #[case::string_literal_unicode_umlaut_two_bytes(r#""\u00e4""#, vec![JsonReadToken::StringLiteral("ä")], None)]
636 #[case::string_literal_unicode_omega_two_bytes(r#""\u03a9""#, vec![JsonReadToken::StringLiteral("Ω")], None)]
637 #[case::string_literal_unicode_euro_three_bytes(r#""\u20ac""#, vec![JsonReadToken::StringLiteral("€")], None)]
638 #[case::string_literal_combined(r#""a\n b\t \u00e4öü \u03a9 12.2\u20ac""#, vec![JsonReadToken::StringLiteral("a\n b\t äöü Ω 12.2€")], None)]
639
640 #[case::number_literal("123", vec![JsonReadToken::NumberLiteral(JsonNumber("123"))], None)]
641 #[case::number_literal_negative("-456", vec![JsonReadToken::NumberLiteral(JsonNumber("-456"))], None)]
642 #[case::number_literal_zero("0", vec![JsonReadToken::NumberLiteral(JsonNumber("0"))], None)]
643 #[case::number_literal_fraction("0.92", vec![JsonReadToken::NumberLiteral(JsonNumber("0.92"))], None)]
644 #[case::number_literal_fraction_small("0.0000000000000092", vec![JsonReadToken::NumberLiteral(JsonNumber("0.0000000000000092"))], None)]
645 #[case::number_literal_fraction_neg("-0.0000000000000092", vec![JsonReadToken::NumberLiteral(JsonNumber("-0.0000000000000092"))], None)]
646 #[case::number_literal_exp_lower("0.92e4", vec![JsonReadToken::NumberLiteral(JsonNumber("0.92e4"))], None)]
647 #[case::number_literal_exp_upper("0.92E6", vec![JsonReadToken::NumberLiteral(JsonNumber("0.92E6"))], None)]
648 #[case::number_literal_pos_exp_lower("0.92e+4", vec![JsonReadToken::NumberLiteral(JsonNumber("0.92e+4"))], None)]
649 #[case::number_literal_pos_exp_upper("0.92E+6", vec![JsonReadToken::NumberLiteral(JsonNumber("0.92E+6"))], None)]
650 #[case::number_literal_neg_exp_lower("0.92e-4", vec![JsonReadToken::NumberLiteral(JsonNumber("0.92e-4"))], None)]
651 #[case::number_literal_neg_exp_upper("0.92E-6", vec![JsonReadToken::NumberLiteral(JsonNumber("0.92E-6"))], None)]
652
653 #[case::number_literal_no_leading_zero(".1", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
654 #[case::no_matching_literal("x", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
655 #[case::invalid_number_continuation("1x", vec![JsonReadToken::NumberLiteral(JsonNumber("1"))], Some(JsonParseError::Parse("missing comma", Location::start())))]
656 #[case::invalid_number_continuation_quote("x\"", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
657
658 #[case::string_literal_unterminated_short(r#""abc "#, vec![], Some(JsonParseError::Parse("unterminated string literal", Location::start())))]
659 #[case::string_literal_unterminated_long(r#""abc "#, vec![], Some(JsonParseError::BufferOverflow(Location::start())))]
660 #[case::string_literal_invalid_escape(r#""\q""#, vec![], Some(JsonParseError::Parse("invalid escape in string literal", Location::start())))]
661 #[case::string_literal_unicode_string_ends(r#""\u004""#, vec![], Some(JsonParseError::Parse("not a four-digit hex number after \\u", Location::start())))]
662 #[case::string_literal_unicode_invalid_character_1(r#""\ux041""#, vec![], Some(JsonParseError::Parse("not a four-digit hex number after \\u", Location::start())))]
663 #[case::string_literal_unicode_invalid_character_2(r#""\u0x41""#, vec![], Some(JsonParseError::Parse("not a four-digit hex number after \\u", Location::start())))]
664 #[case::string_literal_unicode_invalid_character_3(r#""\u00x1""#, vec![], Some(JsonParseError::Parse("not a four-digit hex number after \\u", Location::start())))]
665 #[case::string_literal_unicode_invalid_character_4(r#""\u004x""#, vec![], Some(JsonParseError::Parse("not a four-digit hex number after \\u", Location::start())))]
666 #[case::string_literal_unicode_uppercase_u(r#""\U0041""#, vec![], Some(JsonParseError::Parse("invalid escape in string literal", Location::start())))]
667 #[case::string_literal_unicode_uppercase(r#""\uABCD""#, vec![JsonReadToken::StringLiteral("\u{abcd}")], None)]
668 #[case::string_literal_unicode_mixed_case_1(r#""\uaBcD""#, vec![JsonReadToken::StringLiteral("\u{abcd}")], None)]
669 #[case::string_literal_unicode_mixed_case_2(r#""\uAbCd""#, vec![JsonReadToken::StringLiteral("\u{abcd}")], None)]
670
671 #[case::null_wrong_continuation_1("nul", vec![], Some(JsonParseError::Parse("incomplete null literal", Location::start())))]
672 #[case::null_wrong_continuation_2("nxll", vec![], Some(JsonParseError::Parse("incomplete null literal", Location::start())))]
673 #[case::null_wrong_continuation_3("nUll", vec![], Some(JsonParseError::Parse("incomplete null literal", Location::start())))]
674 #[case::null_wrong_continuation_4("nuxl", vec![], Some(JsonParseError::Parse("incomplete null literal", Location::start())))]
675 #[case::null_wrong_continuation_5("nuLl", vec![], Some(JsonParseError::Parse("incomplete null literal", Location::start())))]
676 #[case::null_wrong_continuation_6("nulx", vec![], Some(JsonParseError::Parse("incomplete null literal", Location::start())))]
677 #[case::null_wrong_continuation_7("nulL", vec![], Some(JsonParseError::Parse("incomplete null literal", Location::start())))]
678 #[case::null_uppercase("Null", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
679 #[case::null_uppercase_2("NULL", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
680
681 #[case::true_wrong_continuation_1("tru", vec![], Some(JsonParseError::Parse("incomplete true literal", Location::start())))]
682 #[case::true_wrong_continuation_2("txue", vec![], Some(JsonParseError::Parse("incomplete true literal", Location::start())))]
683 #[case::true_wrong_continuation_3("tRue", vec![], Some(JsonParseError::Parse("incomplete true literal", Location::start())))]
684 #[case::true_wrong_continuation_4("trxe", vec![], Some(JsonParseError::Parse("incomplete true literal", Location::start())))]
685 #[case::true_wrong_continuation_5("trUe", vec![], Some(JsonParseError::Parse("incomplete true literal", Location::start())))]
686 #[case::true_wrong_continuation_6("trux", vec![], Some(JsonParseError::Parse("incomplete true literal", Location::start())))]
687 #[case::true_wrong_continuation_7("truE", vec![], Some(JsonParseError::Parse("incomplete true literal", Location::start())))]
688 #[case::true_uppercase_1("True", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
689 #[case::true_uppercase_2("TRUE", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
690
691 #[case::false_wrong_continuation_1("fals", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
692 #[case::false_wrong_continuation_2("fxlse", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
693 #[case::false_wrong_continuation_3("fAlse", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
694 #[case::false_wrong_continuation_4("faxse", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
695 #[case::false_wrong_continuation_5("faLse", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
696 #[case::false_wrong_continuation_6("falxe", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
697 #[case::false_wrong_continuation_7("falSe", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
698 #[case::false_wrong_continuation_8("falsx", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
699 #[case::false_wrong_continuation_9("falsE", vec![], Some(JsonParseError::Parse("incomplete false literal", Location::start())))]
700 #[case::false_uppercase_1("False", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
701 #[case::false_uppercase_2("FALSE", vec![], Some(JsonParseError::Parse("invalid JSON literal", Location::start())))]
702
703 #[case::object_end_just_comma(r#"{, }"#, vec![JsonReadToken::StartObject], Some(JsonParseError::Parse("unexpected comma", Location::start())))]
704 #[case::object_end_trailing_comma(r#"{"a": null, }"#, vec![JsonReadToken::StartObject, JsonReadToken::Key("a"), JsonReadToken::NullLiteral], Some(JsonParseError::Parse("trailing comma", Location::start())))]
705 #[case::object_end_after_key(r#"{"a": }"#, vec![JsonReadToken::StartObject, JsonReadToken::Key("a")], Some(JsonParseError::Parse("key without a value", Location::start())))]
706 #[case::array_end_just_comma(r#"[, ]"#, vec![JsonReadToken::StartArray], Some(JsonParseError::Parse("unexpected comma", Location::start())))]
707 #[case::array_end_trailing_comma(r#"[null, ]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("trailing comma", Location::start())))]
708 #[case::array_end_after_key(r#"["a": ]"#, vec![JsonReadToken::StartArray, JsonReadToken::Key("a")], Some(JsonParseError::Parse("key without a value", Location::start())))]
709
710 #[case::missing_comma_null(r#"[null null]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
711 #[case::missing_comma_true(r#"[null true]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
712 #[case::missing_comma_false(r#"[null false]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
713 #[case::missing_comma_number(r#"[null 123]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
714 #[case::missing_comma_string(r#"[null "abc"]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
715 #[case::missing_comma_object(r#"[null {}]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
716 #[case::missing_comma_array(r#"[null []]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
717 #[case::missing_comma_key(r#"{"a": null "b": 1}"#, vec![JsonReadToken::StartObject, JsonReadToken::Key("a"), JsonReadToken::NullLiteral], Some(JsonParseError::Parse("missing comma", Location::start())))]
718 #[case::key_after_key(r#"{"a": "b": 1}"#, vec![JsonReadToken::StartObject, JsonReadToken::Key("a")], Some(JsonParseError::Parse("two keys without value", Location::start())))]
719 #[case::comma_after_key(r#"{"a": , "b": 1}"#, vec![JsonReadToken::StartObject, JsonReadToken::Key("a")], Some(JsonParseError::Parse("unexpected comma", Location::start())))]
720
721 #[case::object_comma_after_comma(r#"{"a": null, ,}"#, vec![JsonReadToken::StartObject, JsonReadToken::Key("a"), JsonReadToken::NullLiteral], Some(JsonParseError::Parse("unexpected comma", Location::start())))]
722 #[case::array_comma_after_comma(r#"[ null, ,]"#, vec![JsonReadToken::StartArray, JsonReadToken::NullLiteral], Some(JsonParseError::Parse("unexpected comma", Location::start())))]
723
724 #[case::object(r#"{ "a": 1, "b": true, "c": "xyz" }"#, vec![
725 JsonReadToken::StartObject,
726 JsonReadToken::Key("a"),
727 JsonReadToken::NumberLiteral(JsonNumber("1")),
728 JsonReadToken::Key("b"),
729 JsonReadToken::BooleanLiteral(true),
730 JsonReadToken::Key("c"),
731 JsonReadToken::StringLiteral("xyz"),
732 JsonReadToken::EndObject,
733 ], None)]
734 #[case::array(r#"[ 6, "xy", true, null ]"#, vec![
735 JsonReadToken::StartArray,
736 JsonReadToken::NumberLiteral(JsonNumber("6")),
737 JsonReadToken::StringLiteral("xy"),
738 JsonReadToken::BooleanLiteral(true),
739 JsonReadToken::NullLiteral,
740 JsonReadToken::EndArray,
741 ], None)]
742 #[case::complex(r#"{"abc":"yo","xyz":"yo","aaaa":["111","11",{},[],null,true,false,-23987,23987,23.235,null,null,23.235e-1,null,null],"ooo":{"lll":"whatever","ar":[]}}"#, vec![
743 JsonReadToken::StartObject,
744 JsonReadToken::Key("abc"),
745 JsonReadToken::StringLiteral("yo"),
746 JsonReadToken::Key("xyz"),
747 JsonReadToken::StringLiteral("yo"),
748 JsonReadToken::Key("aaaa"),
749 JsonReadToken::StartArray,
750 JsonReadToken::StringLiteral("111"),
751 JsonReadToken::StringLiteral("11"),
752 JsonReadToken::StartObject,
753 JsonReadToken::EndObject,
754 JsonReadToken::StartArray,
755 JsonReadToken::EndArray,
756 JsonReadToken::NullLiteral,
757 JsonReadToken::BooleanLiteral(true),
758 JsonReadToken::BooleanLiteral(false),
759 JsonReadToken::NumberLiteral(JsonNumber("-23987")),
760 JsonReadToken::NumberLiteral(JsonNumber("23987")),
761 JsonReadToken::NumberLiteral(JsonNumber("23.235")),
762 JsonReadToken::NullLiteral,
763 JsonReadToken::NullLiteral,
764 JsonReadToken::NumberLiteral(JsonNumber("23.235e-1")),
765 JsonReadToken::NullLiteral,
766 JsonReadToken::NullLiteral,
767 JsonReadToken::EndArray,
768 JsonReadToken::Key("ooo"),
769 JsonReadToken::StartObject,
770 JsonReadToken::Key("lll"),
771 JsonReadToken::StringLiteral("whatever"),
772 JsonReadToken::Key("ar"),
773 JsonReadToken::StartArray,
774 JsonReadToken::EndArray,
775 JsonReadToken::EndObject,
776 JsonReadToken::EndObject,
777 ], None)]
778
779 fn test_parse(#[case] input: &str, #[case] expected: Vec<JsonReadToken>, #[case] expected_error: Option<JsonParseError<std::io::Error>>) {
780 let input_with_whitespace = format!(" \r\n\t{} \r\n\t", input);
781
782 {
783 let mut r = Cursor::new(input.as_bytes());
784 let mut json_reader = JsonReader::new(64, &mut r);
785 for evt in &expected {
786 let parsed_evt = json_reader.next();
787 assert_eq!(&parsed_evt.unwrap(), evt);
788 }
789 if let Some(expected_error) = &expected_error {
790 match json_reader.next() {
791 Ok(_) => panic!("expected error but was ok: {}", expected_error),
792 Err(e) => assert_is_similar_error(&e, expected_error),
793 }
794 }
795 else {
796 assert_eq!(json_reader.next().unwrap(), JsonReadToken::EndOfStream);
797 }
798 }
799 {
800 let mut r = Cursor::new(input_with_whitespace.as_bytes());
801 let mut json_reader = JsonReader::new(64, &mut r);
802 for evt in &expected {
803 assert_eq!(&json_reader.next().unwrap(), evt);
804 }
805 if let Some(expected_error) = &expected_error {
806 match json_reader.next() {
807 Ok(_) => panic!("expected error but was ok: {}", expected_error),
808 Err(e) => assert_is_similar_error(&e, expected_error),
809 }
810 }
811 else {
812 assert_eq!(json_reader.next().unwrap(), JsonReadToken::EndOfStream);
813 }
814 }
815 }
816
817 #[test]
818 fn test_provided_buffer_fits() -> Result<(), JsonParseError<io::Error>> {
819 let mut r = Cursor::new(b"123".to_vec());
820 let mut reader = JsonReader::new(8, &mut r);
821 assert_eq!(reader.next()?, JsonReadToken::NumberLiteral(JsonNumber("123")));
822 assert_eq!(reader.next()?, JsonReadToken::EndOfStream);
823 Ok(())
824 }
825
826 #[test]
827 fn test_provided_buffer_overflow() -> Result<(), JsonParseError<io::Error>> {
828 let mut r = Cursor::new(b"\"123 123 x\"".to_vec());
829 let mut reader = JsonReader::new(8, &mut r);
830 match reader.next() {
831 Ok(_) => panic!("expected an error"),
832 Err(e) => assert_is_similar_error(&e, &JsonParseError::BufferOverflow(Location::start())),
833 }
834 Ok(())
835 }
836
837 #[rstest]
838 #[case::simple("1", Some(1), Some(1), 1.0, 1.0)]
839 #[case::big("1345678345", Some(1345678345), Some(1345678345), 1345678345.0, 1345678345.0)]
840 #[case::bigger("3345678345", Some(3345678345), None, 3345678345.0, 3345678345.0)]
841 #[case::too_big("13456783459", None, None, 13456783459.0, 13456783459.0)]
842 #[case::negative("-1", None, Some(-1), -1.0, -1.0)]
843 #[case::fract("1.0", None, None, 1.0, 1.0)]
844 #[case::exp("1e3", None, None, 1e3, 1e3)]
845 #[case::neg_exp("1e-3", None, None, 1e-3, 1e-3)]
846 #[case::pos_exp("1e+3", None, None, 1e3, 1e3)]
847 #[case::fract_exp("1.23e3", None, None, 1230.0, 1230.0)]
848 #[case::fract_neg_exp("1.23e-3", None, None, 1.23e-3, 1.23e-3)]
849 #[case::fract_pos_exp("1.23e+3", None, None, 1.23e3, 1.23e3)]
850 fn test_json_number_parse(#[case] s: &str, #[case] expected_u32: Option<u32>, #[case] expected_i32: Option<i32>, #[case] expected_f64: f64, #[case] expected_f32: f32) {
851 let n = JsonNumber(s);
852
853 {
854 let parsed = n.parse::<u32>();
855 match expected_u32 {
856 Some(e) => assert_eq!(e, parsed.unwrap()),
857 None => assert!(parsed.is_err()),
858 }
859 }
860 {
861 let parsed = n.parse::<i32>();
862 match expected_i32 {
863 Some(e) => assert_eq!(e, parsed.unwrap()),
864 None => assert!(parsed.is_err()),
865 }
866 }
867 {
868 let parsed = n.parse::<f64>();
869 assert_eq!(expected_f64, parsed.unwrap());
870 }
871 {
872 let parsed = n.parse::<f32>();
873 assert_eq!(expected_f32, parsed.unwrap());
874 }
875 }
876
877
878 #[rstest]
879 #[case::simple(Location::start(), vec![b'a'], Location { offset: 1, line: 1, column: 2,})]
880 #[case::cr(Location::start(), vec![b'\r'], Location { offset: 1, line: 1, column: 2,})]
881 #[case::tab(Location::start(), vec![b'\t'], Location { offset: 1, line: 1, column: 2,})]
882 #[case::nl(Location::start(), vec![b'\n'], Location { offset: 1, line: 2, column: 1,})]
883 #[case::in_line(Location::start(), vec![b'\r', b'\n', b'\n', b'x', b'y'], Location { offset: 5, line: 3, column: 3,})]
884 #[case::sequence(Location::start(), vec![b'a', b'b', b'\n', b'x', b'\n'], Location { offset: 5, line: 3, column: 1,})]
885 fn test_location_after_byte(#[case] mut initial: Location, #[case] bytes: Vec<u8>, #[case] expected: Location) {
886 for byte in bytes {
887 initial.after_byte(byte);
888 }
889 assert_eq!(initial, expected);
890 }
891
892
893 #[rstest]
894 #[case::key(r#""abc": null"#, Some(Some("abc")))]
895 #[case::other_key(r#""xyz": null"#, Some(Some("xyz")))]
896 #[case::end_object(r#"}"#, Some(None))]
897 #[case::null(r#"null"#, None)]
898 #[case::bool(r#"true"#, None)]
899 #[case::number(r#"1"#, None)]
900 #[case::string(r#""a""#, None)]
901 #[case::start_object(r#"{"#, None)]
902 #[case::start_array(r#"["#, None)]
903 #[case::end_array(r#"]"#, None)]
904 fn test_expect_next_key(#[case] json: &str, #[case] expected: Option<Option<&str>>) {
905 let mut r = Cursor::new(json.as_bytes());
906 let mut json_reader = JsonReader::new(64, &mut r);
907 match json_reader.expect_next_key() {
908 Ok(actual) => assert_eq!(actual, expected.unwrap()),
909 Err(JsonParseError::UnexpectedToken(_,_)) => assert!(expected.is_none()),
910 Err(e) => panic!("unexpected error: {}", e)
911 }
912 }
913
914 #[rstest]
915 #[case::simple("1", Ok(1))]
916 #[case::other_number("500", Err(JsonParseError::Parse("invalid number", Location::start())))]
917 #[case::null("null", Err(JsonParseError::UnexpectedToken("", Location::start())))]
918 #[case::string("\"abc\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
919 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
920 #[case::bool("true", Err(JsonParseError::UnexpectedToken("", Location::start())))]
921 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
922 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
923 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
924 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
925 fn test_expect_next_number(#[case] json: &str, #[case] expected_num: JsonParseResult<u8, io::Error>) {
926 let mut r = Cursor::new(json.as_bytes());
927 let mut json_reader = JsonReader::new(64, &mut r);
928 match json_reader.expect_next_number::<u8>() {
929 Ok(n) => assert_eq!(n, expected_num.unwrap()),
930 Err(act_e) => match expected_num {
931 Ok(_) => panic!("unexpected error: {}", act_e),
932 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
933 }
934 }
935 }
936
937 #[rstest]
938 #[case::simple("1", Ok(Some(1)))]
939 #[case::other_number("500", Err(JsonParseError::Parse("invalid number", Location::start())))]
940 #[case::null("null", Ok(None))]
941 #[case::string("\"abc\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
942 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
943 #[case::bool("true", Err(JsonParseError::UnexpectedToken("", Location::start())))]
944 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
945 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
946 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
947 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
948 fn test_expect_next_opt_number(#[case] json: &str, #[case] expected_num: JsonParseResult<Option<u8>, io::Error>) {
949 let mut r = Cursor::new(json.as_bytes());
950 let mut json_reader = JsonReader::new(64, &mut r);
951 match json_reader.expect_next_opt_number::<u8>() {
952 Ok(n) => assert_eq!(n, expected_num.unwrap()),
953 Err(act_e) => match expected_num {
954 Ok(_) => panic!("unexpected error: {}", act_e),
955 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
956 }
957 }
958 }
959
960 #[test]
961 fn test_expect_next_raw_number() {
962 let json = " 123.45 ";
963 let mut r = Cursor::new(json.as_bytes());
964 let mut json_reader = JsonReader::new(64, &mut r);
965 let actual = json_reader.expect_next_raw_number().unwrap();
966 assert_eq!(actual, JsonNumber("123.45"));
967 }
968
969 #[rstest]
970 #[case::number(" 5 ", Ok(Some(JsonNumber("5"))))]
971 #[case::null(" null ", Ok(None))]
972 #[case::boolean(" true ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
973 fn test_expect_next_opt_raw_number(#[case] json: &str, #[case] expected_num: JsonParseResult<Option<JsonNumber>, io::Error>) {
974 let mut r = Cursor::new(json.as_bytes());
975 let mut json_reader = JsonReader::new(64, &mut r);
976 match json_reader.expect_next_opt_raw_number() {
977 Ok(o) => assert_eq!(o, expected_num.unwrap()),
978 Err(act_e) => match expected_num {
979 Ok(_) => panic!("unexpected error: {}", act_e),
980 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
981 }
982
983 }
984 }
985
986 #[rstest]
987 #[case::simple("\"qrs\"", Ok("qrs"))]
988 #[case::null("null", Err(JsonParseError::UnexpectedToken("", Location::start())))]
989 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
990 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
991 #[case::bool("true", Err(JsonParseError::UnexpectedToken("", Location::start())))]
992 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
993 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
994 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
995 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
996 fn test_expect_next_string(#[case] json: &str, #[case] expected: JsonParseResult<&str, io::Error>) {
997 let mut r = Cursor::new(json.as_bytes());
998 let mut json_reader = JsonReader::new(64, &mut r);
999 match json_reader.expect_next_string() {
1000 Ok(n) => assert_eq!(n, expected.unwrap()),
1001 Err(act_e) => match expected {
1002 Ok(_) => panic!("unexpected error: {}", act_e),
1003 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1004 }
1005 }
1006 }
1007
1008 #[rstest]
1009 #[case::simple("\"rst\"", Ok(Some("rst")))]
1010 #[case::null("null", Ok(None))]
1011 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1012 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1013 #[case::bool("true", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1014 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1015 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1016 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1017 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1018 fn test_expect_next_opt_string(#[case] json: &str, #[case] expected: JsonParseResult<Option<&str>, io::Error>) {
1019 let mut r = Cursor::new(json.as_bytes());
1020 let mut json_reader = JsonReader::new(64, &mut r);
1021 match json_reader.expect_next_opt_string() {
1022 Ok(n) => assert_eq!(n, expected.unwrap()),
1023 Err(act_e) => match expected {
1024 Ok(_) => panic!("unexpected error: {}", act_e),
1025 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1026 }
1027 }
1028 }
1029 #[rstest]
1030 #[case::bool_true("true", Ok(true))]
1031 #[case::bool_false("false", Ok(false))]
1032 #[case::null("null", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1033 #[case::string("\"a\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1034 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1035 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1036 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1037 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1038 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1039 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1040 fn test_expect_next_bool(#[case] json: &str, #[case] expected: JsonParseResult<bool, io::Error>) {
1041 let mut r = Cursor::new(json.as_bytes());
1042 let mut json_reader = JsonReader::new(64, &mut r);
1043 match json_reader.expect_next_bool() {
1044 Ok(n) => assert_eq!(n, expected.unwrap()),
1045 Err(act_e) => match expected {
1046 Ok(_) => panic!("unexpected error: {}", act_e),
1047 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1048 }
1049 }
1050 }
1051
1052 #[rstest]
1053 #[case::bool_true("true", Ok(Some(true)))]
1054 #[case::bool_false("false", Ok(Some(false)))]
1055 #[case::null("null", Ok(None))]
1056 #[case::string("\"x\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1057 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1058 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1059 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1060 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1061 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1062 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1063 fn test_expect_next_opt_bool(#[case] json: &str, #[case] expected: JsonParseResult<Option<bool>, io::Error>) {
1064 let mut r = Cursor::new(json.as_bytes());
1065 let mut json_reader = JsonReader::new(64, &mut r);
1066 match json_reader.expect_next_opt_bool() {
1067 Ok(n) => assert_eq!(n, expected.unwrap()),
1068 Err(act_e) => match expected {
1069 Ok(_) => panic!("unexpected error: {}", act_e),
1070 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1071 }
1072 }
1073 }
1074
1075 #[rstest]
1076 #[case::null("null", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1077 #[case::bool("true", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1078 #[case::string("\"a\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1079 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1080 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1081 #[case::start_object("{", Ok(()))]
1082 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1083 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1084 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1085 fn test_expect_next_start_object(#[case] json: &str, #[case] expected: JsonParseResult<(), io::Error>) {
1086 let mut r = Cursor::new(json.as_bytes());
1087 let mut json_reader = JsonReader::new(64, &mut r);
1088 match json_reader.expect_next_start_object() {
1089 Ok(n) => assert_eq!(n, expected.unwrap()),
1090 Err(act_e) => match expected {
1091 Ok(_) => panic!("unexpected error: {}", act_e),
1092 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1093 }
1094 }
1095 }
1096
1097 #[rstest]
1098 #[case::bool("false", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1099 #[case::null("null", Ok(None))]
1100 #[case::string("\"x\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1101 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1102 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1103 #[case::start_object("{", Ok(Some(())))]
1104 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1105 #[case::start_array("[", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1106 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1107 fn test_expect_next_opt_start_object(#[case] json: &str, #[case] expected: JsonParseResult<Option<()>, io::Error>) {
1108 let mut r = Cursor::new(json.as_bytes());
1109 let mut json_reader = JsonReader::new(64, &mut r);
1110 match json_reader.expect_next_opt_start_object() {
1111 Ok(n) => assert_eq!(n, expected.unwrap()),
1112 Err(act_e) => match expected {
1113 Ok(_) => panic!("unexpected error: {}", act_e),
1114 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1115 }
1116 }
1117 }
1118
1119 #[rstest]
1120 #[case::null("null", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1121 #[case::bool("true", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1122 #[case::string("\"a\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1123 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1124 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1125 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1126 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1127 #[case::start_array("[", Ok(()))]
1128 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1129 fn test_expect_next_start_array(#[case] json: &str, #[case] expected: JsonParseResult<(), io::Error>) {
1130 let mut r = Cursor::new(json.as_bytes());
1131 let mut json_reader = JsonReader::new(64, &mut r);
1132 match json_reader.expect_next_start_array() {
1133 Ok(n) => assert_eq!(n, expected.unwrap()),
1134 Err(act_e) => match expected {
1135 Ok(_) => panic!("unexpected error: {}", act_e),
1136 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1137 }
1138 }
1139 }
1140
1141 #[rstest]
1142 #[case::bool("false", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1143 #[case::null("null", Ok(None))]
1144 #[case::string("\"x\"", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1145 #[case::number("12", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1146 #[case::key("\"abc\": ", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1147 #[case::start_object("{", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1148 #[case::end_object("}", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1149 #[case::start_array("[", Ok(Some(())))]
1150 #[case::end_array("]", Err(JsonParseError::UnexpectedToken("", Location::start())))]
1151 fn test_expect_next_opt_start_array(#[case] json: &str, #[case] expected: JsonParseResult<Option<()>, io::Error>) {
1152 let mut r = Cursor::new(json.as_bytes());
1153 let mut json_reader = JsonReader::new(64, &mut r);
1154 match json_reader.expect_next_opt_start_array() {
1155 Ok(n) => assert_eq!(n, expected.unwrap()),
1156 Err(act_e) => match expected {
1157 Ok(_) => panic!("unexpected error: {}", act_e),
1158 Err(exp_e) => assert_is_similar_error(&act_e, &exp_e),
1159 }
1160 }
1161 }
1162
1163 #[test]
1164 fn test_with_lenient_comma() {
1165 let json = r#"
1166 { "a": 1}
1167 { "a": 2}
1168 "#;
1169
1170 {
1171 let mut r = Cursor::new(json.as_bytes());
1172 let result = try_read_json_lines(&mut JsonReader::new(64, &mut r));
1173 assert!(result.is_err());
1174 }
1175
1176 {
1177 let mut r = Cursor::new(json.as_bytes());
1178 let result = try_read_json_lines(&mut JsonReader::new_with_lenient_comma_handling(64, &mut r));
1179 assert_eq!(result.unwrap(), vec![1, 2]);
1180 }
1181 }
1182
1183 fn try_read_json_lines<R: Read>(json_reader: &mut JsonReader<Vec<u8>, R>) -> JsonParseResult<Vec<u32>, io::Error> {
1184 let mut result = Vec::new();
1185 while json_reader.next()? == JsonReadToken::StartObject {
1186 loop {
1187 match json_reader.expect_next_key()? {
1188 Some("a") => result.push( json_reader.expect_next_number()?),
1189 Some(_) => json_reader.skip_value()?,
1190 None => break,
1191 }
1192 }
1193 }
1194 Ok(result)
1195 }
1196
1197 #[rstest]
1198 #[case::end_object_empty("}, 77", false)]
1199 #[case::end_object_simple(r#" "a": 10, "b": null }, 77"#, false)]
1200 #[case::end_object_nested(r#" "a": 10, "x": { "q": 99, "r": [1, 2, 3] }, "b": null }, 77"#, false)]
1201 #[case::end_array_empty("], 77", false)]
1202 #[case::end_array_simple(r#"99, "abc", null, true], 77"#, false)]
1203 #[case::end_array_nested(r#"99, [1, [], true, {"abc": { "xyz": [1, 2, 3]}}], "abc", null, true], 77"#, false)]
1204 #[case::number("1, 77", true)]
1205 #[case::boolean("true, 77", true)]
1206 #[case::null("null, 77", true)]
1207 fn test_skip_to_end_of_current_scope(#[case] json: &str, #[case] should_fail: bool) -> JsonParseResult<(), io::Error> {
1208 let mut r = Cursor::new(json.as_bytes());
1209 let mut json_reader = JsonReader::new(64, &mut r);
1210 match json_reader.skip_to_end_of_current_scope() {
1211 Ok(_) => {
1212 assert!(!should_fail);
1213 assert_eq!(77, json_reader.expect_next_number::<u32>()?);
1214 }
1215 Err(_) => {
1216 assert!(should_fail);
1217 }
1218 }
1219 Ok(())
1220 }
1221
1222 #[rstest]
1223 #[case::number(r#"123, 77"#, false)]
1224 #[case::string(r#""abc", 77"#, false)]
1225 #[case::boolean(r#"true, 77"#, false)]
1226 #[case::null(r#"null, 77"#, false)]
1227 #[case::object_empty(r#"{}, 77"#, false)]
1228 #[case::object_simple(r#"{ "a": 10, "b": null }, 77"#, false)]
1229 #[case::object_nested(r#"{ "a": 10, "x": { "q": 99, "r": [1, 2, 3] }, "b": null }, 77"#, false)]
1230 #[case::array_empty("[], 77", false)]
1231 #[case::array_simple(r#"[99, "abc", null, true], 77"#, false)]
1232 #[case::array_nested(r#"[99, [1, [], true, {"abc": { "xyz": [1, 2, 3]}}], "abc", null, true], 77"#, false)]
1233 fn test_skip_value(#[case] json: &str, #[case] should_fail: bool) -> JsonParseResult<(), io::Error> {
1234 let mut r = Cursor::new(json.as_bytes());
1235 let mut json_reader = JsonReader::new(64, &mut r);
1236 match json_reader.skip_value() {
1237 Ok(_) => {
1238 assert!(!should_fail);
1239 assert_eq!(77, json_reader.expect_next_number::<u32>()?);
1240 }
1241 Err(_) => {
1242 assert!(should_fail);
1243 }
1244 }
1245 Ok(())
1246 }
1247}