json_streaming/blocking/
read.rs

1use crate::blocking::io::BlockingRead;
2use core::str::FromStr;
3use crate::shared::*;
4
5/// A [JsonReader] wraps a sequence of bytes, aggregating them into a sequence of JSON tokens. It
6///  is in essentially a tokenizer, adding some rudimentary convenience for JSON's grammar.
7///
8/// It does *not* try to be a full-blown JSON parser. The reason is that if an application consumes
9///  an actual JSON document, it assumes structure beyond the document being a valid JSON document
10///  ('name is a mandatory string, age is a u32, but it is ok if it is null or not present in the
11///  first place'). [JsonReader] makes it easy for application code to consume data based on such
12///  assumptions - and while it does, application code checks the document's conformity to the JSON
13///  grammar automatically.
14///
15/// A [JsonReader] wraps and consumes a [BlockingRead] which is basically a same abstraction as a
16///  [std::io::Read] but without enforcing the dependency on `std`. For the majority of users who
17///  don't care about that, there is a blanket implementation of [BlockingRead] for [std::io::Read],
18///  letting you ignore distinction between the two.
19///
20/// The [JsonReader] holds a mutable reference to the reader rather than taking ownership of it.
21///  That means it needs to have a lifetime parameter, allowing the compiler to ensure that the
22///  reader lives at least as long as the wrapping [JsonReader].
23///
24/// The [JsonReader] also holds a fixed read buffer which it uses to assemble tokens. [JsonReader]
25///  can either work with a buffer passed to it on construction, or it can allocate the buffer as a
26///  convenience, and it does not do *any* memory allocation on the heap beyond that.
27///
28/// The buffer is fixed in length, and if some token (e.g. a string value) does not fit into the
29///  buffer, that causes a failure. While this may look like an inconvenient restriction, it is
30///  actually an important security safeguard: JSON documents often come from external sources and
31///  have limited trustworthiness at best. Without an upper bound on token size, a maliciously or
32///  negligently created document could contain a string literal with a size of a gigabyte,
33///  working as a denial-of-service attack. JSON parsers that work on materialized documents often
34///  address this by placing a restriction on the maximum size of the whole document.
35///
36/// The following code snippet shows a small working example of reading a JSON document with a
37///  single object:
38///
39/// ```
40/// use json_streaming::blocking::*;
41/// use json_streaming::shared::*;
42///
43/// fn read_something(r: &mut impl std::io::Read) -> JsonParseResult<(), std::io::Error> {
44///     let mut json_reader = JsonReader::new(1024, r);
45///
46///     json_reader.expect_next_start_object()?;
47///     loop {
48///         match json_reader.expect_next_key()? {
49///             Some("a") => println!("a: {}", json_reader.expect_next_string()?),
50///             Some("b") => println!("b: {}", json_reader.expect_next_string()?),
51///             Some(_other) => {
52///                 return Err(JsonParseError::Parse("unexpected key parsing 'person'", json_reader.location()));
53///             },
54///             None => break,
55///         }
56///     }
57///     Ok(())
58/// }
59/// ```
60pub 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    /// Create a [JsonReader], allocating a read buffer of given size on the heap.
68    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    /// Create a [JsonReader] without requiring commas between objects. This is intended for
74    ///  reading [https://jsonlines.org] documents - see the `jsonlines.rs` example for details.
75    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    /// Create a [JsonReader] that uses an externally provided buffer as its read buffer. The main
83    ///  reason to do this is to avoid heap allocation in a no-std environment.
84    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    /// Return the next JSON token. This is the work horse of [JsonReader] and the foundation for
92    ///  other convenience abstraction.
93    ///
94    /// The function does only limited checks of JSON grammar and basically returns whatever tokens
95    ///  it finds.
96    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(), // key or string value based on following ':'
142            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    /// This is the function for the loop to read the members of a JSON object: It returns either
153    ///  a JSON key or `None` if it encounters the `}` that ends the object. All other tokens are
154    ///  invalid and cause the function to fail.
155    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    /// Returns a JSON number as a [JsonNumber], and fails if the next token is anything other
166    ///  than a number. That includes the case that the next token is `null` - if the number
167    ///  is optional and `null` a valid value, use [JsonReader::expect_next_opt_raw_number] instead.
168    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    /// Returns a [JsonNumber] if the next token is a JSON number, or `None` if the next token
178    ///  is `null`. All other tokens cause the function to fail.
179    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    /// Returns a number parsed to an application-provided type, failing if the next token is not
190    ///  a JSON number or the number is not parseable to the provided type (e.g. trying to
191    ///  get retrieve a floating point number as a u32).
192    ///
193    /// The expected numeric type can be provided explicitly, like this:
194    /// ```
195    /// # use json_streaming::blocking::*;
196    /// # use json_streaming::shared::*;
197    /// # fn get_num() -> JsonParseResult<(), std::io::Error> {
198    /// # let buf = "123";
199    /// # let mut r = std::io::Cursor::new(buf);
200    /// # let mut json_reader = JsonReader::new(128, &mut r);
201    /// let n = json_reader.expect_next_number::<u32>()?;
202    /// # Ok(()) }
203    /// ```
204    /// or inferred by the compiler:
205    /// ```
206    /// # use json_streaming::blocking::*;
207    /// # use json_streaming::shared::*;
208    /// # fn get_num() -> JsonParseResult<(), std::io::Error> {
209    /// # let buf = "123";
210    /// # let mut r = std::io::Cursor::new(buf);
211    /// # let mut json_reader = JsonReader::new(128, &mut r);
212    /// let n:u32 = json_reader.expect_next_number()?;
213    /// # Ok(()) }
214    /// ```
215    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    /// The same as [JsonReader::expect_next_number], but accepting a `null` literal which it
224    ///  returns as `None`.
225    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    /// If the next token is a string literal, return that, and fail for any other token.
239    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    /// The same as [JsonReader::expect_next_string], but accepting a `null` literal which is
249    ///  returned as `None`.
250    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    /// `true` and `false` literals are returned as a boolean token, all other tokens cause the
261    ///  function to fail.
262    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    /// The same as [JsonReader::expect_next_bool], but accepting a `null` literal which is
272    ///  returned as `None`.
273    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    /// Fails for any token except the `{` that starts an object.
284    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    /// The same as [JsonReader::expect_next_start_object], but accepting a `null` literal which is
294    ///  returned as `None`.
295    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    /// Fails for any token except the `[` that starts an array.
306    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    /// The same as [JsonReader::expect_next_start_array], but accepting a `null` literal which is
316    ///  returned as `None`.
317    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    /// This function assumes that it is called inside an object or array, and silently consumes
328    ///  all tokens until and including the closing `}` or `]`.
329    ///
330    /// This function is useful for gracefully ignoring array elements with an unsupported type. See
331    ///  the `skipping.rs` example for details.
332    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    /// This function skips the value starting with the next token. This can be a single-token value,
357    ///  but it can also be an object or array of unknown structure and nesting depth, in which
358    ///  case this function silently consumes tokens until it reaches the matching closing `}` or
359    ///  `]`.
360    ///
361    /// This function is useful for gracefully ignoring object members with an unknown key - see
362    ///  the `skipping.rs` example for details.
363    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        // Parsing JSON requires a lookahead of a single byte, which is stored in 'parked_next'
400        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        // the buffer contains the string's contents - the next character determines whether this
490        //  is key or a string value. Recall that we don't check for valid JSON.
491
492        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        // exactly four hex digits specifying a code point
519        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    /// Returns the current parse location in the underlying reader - offset, row and column.
560    #[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}