core_json/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc = include_str!("../README.md")]
3#![deny(missing_docs)]
4#![no_std]
5
6#[cfg(feature = "alloc")]
7extern crate alloc;
8
9mod io;
10mod stack;
11mod string;
12mod number;
13
14pub(crate) use io::*;
15pub use io::BytesLike;
16pub use stack::*;
17use string::*;
18
19/// An error incurred when deserializing.
20#[derive(Debug)]
21pub enum JsonError<'bytes, B: BytesLike<'bytes>, S: Stack> {
22  /// An unexpected state was reached during deserialization.
23  InternalError,
24  /// An error from the bytes.
25  BytesError(B::Error),
26  /// An error from the stack.
27  StackError(S::Error),
28  /// The deserializer was reused.
29  ReusedDeserializer,
30  /// The JSON had an invalid key.
31  InvalidKey,
32  /// The JSON had an invalid delimiter between the key and value (`:` expected).
33  InvalidKeyValueDelimiter,
34  /// The JSON had an invalid value.
35  InvalidValue,
36  /// The JSON had a trailing comma.
37  TrailingComma,
38  /// The JSON had mismatched delimiters between the open and close of the structure.
39  MismatchedDelimiter,
40  /// Operation could not be performed given the value's type.
41  TypeError,
42}
43impl<'bytes, B: BytesLike<'bytes>, S: Stack> Clone for JsonError<'bytes, B, S> {
44  #[inline(always)]
45  fn clone(&self) -> Self {
46    *self
47  }
48}
49impl<'bytes, B: BytesLike<'bytes>, S: Stack> Copy for JsonError<'bytes, B, S> {}
50
51/// Interpret the immediate value within the bytes as a `bool`.
52#[inline(always)]
53pub fn as_bool<'bytes, B: BytesLike<'bytes>, S: Stack>(
54  bytes: &B,
55) -> Result<bool, JsonError<'bytes, B, S>> {
56  let first = bytes.peek(0).ok();
57  let second = bytes.peek(1).ok();
58  let third = bytes.peek(2).ok();
59  let fourth = bytes.peek(3).ok();
60  let fifth = bytes.peek(4).ok();
61
62  let is_true = (first, second, third, fourth) == (Some(b't'), Some(b'r'), Some(b'u'), Some(b'e'));
63  let is_false = (first, second, third, fourth, fifth) ==
64    (Some(b'f'), Some(b'a'), Some(b'l'), Some(b's'), Some(b'e'));
65
66  if !(is_true | is_false) {
67    Err(JsonError::TypeError)?;
68  }
69
70  Ok(is_true)
71}
72
73/// Check if the immediate value within the bytes is `null`.
74#[inline(always)]
75pub fn is_null<'bytes, B: BytesLike<'bytes>, S: Stack>(
76  bytes: &B,
77) -> Result<bool, JsonError<'bytes, B, S>> {
78  let first = bytes.peek(0).ok();
79  let second = bytes.peek(1).ok();
80  let third = bytes.peek(2).ok();
81  let fourth = bytes.peek(3).ok();
82
83  Ok((first, second, third, fourth) == (Some(b'n'), Some(b'u'), Some(b'l'), Some(b'l')))
84}
85
86/// Advance the bytes until there's a non-whitespace character.
87#[inline(always)]
88fn advance_whitespace<'bytes, B: BytesLike<'bytes>, S: Stack>(
89  bytes: &mut B,
90) -> Result<(), JsonError<'bytes, B, S>> {
91  loop {
92    let next = bytes.peek(0).map_err(JsonError::BytesError)?;
93    // https://datatracker.ietf.org/doc/html/rfc8259#section-2 defines whitespace as follows
94    if !matches!(next, b'\x20' | b'\x09' | b'\x0A' | b'\x0D') {
95      break;
96    }
97    bytes.advance(1).map_err(JsonError::BytesError)?;
98  }
99  Ok(())
100}
101
102/// Advance past a comma, or to the close of the structure.
103fn advance_past_comma_or_to_close<'bytes, B: BytesLike<'bytes>, S: Stack>(
104  bytes: &mut B,
105) -> Result<(), JsonError<'bytes, B, S>> {
106  advance_whitespace(bytes)?;
107  match bytes.peek(0).map_err(JsonError::BytesError)? {
108    b',' => {
109      bytes.advance(1).map_err(JsonError::BytesError)?;
110      advance_whitespace(bytes)?;
111      if matches!(bytes.peek(0).map_err(JsonError::BytesError)?, b']' | b'}') {
112        Err(JsonError::TrailingComma)?;
113      }
114    }
115    b']' | b'}' => {}
116    _ => Err(JsonError::InvalidValue)?,
117  }
118  Ok(())
119}
120
121/// The result from a single step of the deserialized, if within an object.
122enum SingleStepObjectResult<'bytes, B: BytesLike<'bytes>> {
123  /// A field within the object was advanced to.
124  Field {
125    /// The key for this field.
126    key: String<'bytes, B>,
127  },
128  /// The object was closed.
129  Closed,
130}
131
132/// The result from a single step of the deserialized, if within an array.
133enum SingleStepArrayResult {
134  /// A value within the array was advanced to.
135  Value,
136  /// The array was closed.
137  Closed,
138}
139
140/// The result from a single step of the deserializer, if handling an unknown value.
141enum SingleStepUnknownResult<'bytes, B: BytesLike<'bytes>> {
142  /// An object was opened.
143  ObjectOpened,
144  /// An array was opened.
145  ArrayOpened,
146  /// A string was read.
147  String(String<'bytes, B>),
148  /// A unit value was advanced past.
149  Advanced,
150}
151
152/// The result from a single step of the deserializer.
153enum SingleStepResult<'bytes, B: BytesLike<'bytes>> {
154  /// The result if within an object.
155  Object(SingleStepObjectResult<'bytes, B>),
156  /// The result if within an array.
157  Array(SingleStepArrayResult),
158  /// The result if handling an unknown value.
159  Unknown(SingleStepUnknownResult<'bytes, B>),
160}
161
162/// Step the deserializer forwards.
163///
164/// This assumes there is no leading whitespace present in `bytes` and will advance past any
165/// whitespace present before the next logical unit.
166fn single_step<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack>(
167  bytes: &'parent mut B,
168  stack: &'parent mut S,
169) -> Result<SingleStepResult<'bytes, B>, JsonError<'bytes, B, S>> {
170  match stack.peek().ok_or(JsonError::InternalError)? {
171    State::Object => {
172      let next = bytes.read_byte().map_err(JsonError::BytesError)?;
173
174      // Check if the object terminates
175      if next == b'}' {
176        stack.pop().ok_or(JsonError::InternalError)?;
177
178        // If this isn't the outer object, advance past the comma after
179        if stack.depth() != 0 {
180          advance_past_comma_or_to_close(bytes)?;
181        }
182
183        return Ok(SingleStepResult::Object(SingleStepObjectResult::Closed));
184      }
185
186      // Read the name of this field
187      if next != b'"' {
188        Err(JsonError::InvalidKey)?;
189      }
190      let key = read_string(bytes)?;
191
192      // Read the colon delimiter
193      advance_whitespace::<_, S>(bytes)?;
194      if bytes.read_byte().map_err(JsonError::BytesError)? != b':' {
195        Err(JsonError::InvalidKeyValueDelimiter)?;
196      }
197
198      // Push how we're reading a value of an unknown type onto the stack
199      advance_whitespace::<_, S>(bytes)?;
200      stack.push(State::Unknown).map_err(JsonError::StackError)?;
201      Ok(SingleStepResult::Object(SingleStepObjectResult::Field { key }))
202    }
203    State::Array => {
204      // Check if the array terminates
205      if bytes.peek(0).map_err(JsonError::BytesError)? == b']' {
206        stack.pop().ok_or(JsonError::InternalError)?;
207        bytes.advance(1).map_err(JsonError::BytesError)?;
208
209        // If this isn't the outer object, advance past the comma after
210        if stack.depth() != 0 {
211          advance_past_comma_or_to_close(bytes)?;
212        }
213
214        return Ok(SingleStepResult::Array(SingleStepArrayResult::Closed));
215      }
216
217      // Since the array doesn't terminate, read the next value
218      stack.push(State::Unknown).map_err(JsonError::StackError)?;
219      Ok(SingleStepResult::Array(SingleStepArrayResult::Value))
220    }
221    State::Unknown => {
222      stack.pop().ok_or(JsonError::InternalError)?;
223
224      let mut result = SingleStepResult::Unknown(SingleStepUnknownResult::Advanced);
225      match bytes.peek(0).map_err(JsonError::BytesError)? {
226        // Handle if this opens an object
227        b'{' => {
228          bytes.advance(1).map_err(JsonError::BytesError)?;
229          advance_whitespace(bytes)?;
230          stack.push(State::Object).map_err(JsonError::StackError)?;
231          return Ok(SingleStepResult::Unknown(SingleStepUnknownResult::ObjectOpened));
232        }
233        // Handle if this opens an array
234        b'[' => {
235          bytes.advance(1).map_err(JsonError::BytesError)?;
236          advance_whitespace(bytes)?;
237          stack.push(State::Array).map_err(JsonError::StackError)?;
238          return Ok(SingleStepResult::Unknown(SingleStepUnknownResult::ArrayOpened));
239        }
240        // Handle if this opens an string
241        b'"' => {
242          bytes.advance(1).map_err(JsonError::BytesError)?;
243          // Read past the string
244          result = SingleStepResult::Unknown(SingleStepUnknownResult::String(read_string(bytes)?));
245        }
246        // This is a distinct unit value
247        _ => {
248          // https://datatracker.ietf.org/doc/html/rfc8259#section-3 defines all possible values
249          let is_number = match number::as_number(bytes) {
250            Ok((len, _)) => Some(len),
251            Err(JsonError::TypeError) => None,
252            Err(e) => Err(e)?,
253          };
254          let is_bool = match as_bool(bytes) {
255            Ok(value) => Some(if value { 4 } else { 5 }),
256            Err(JsonError::TypeError) => None,
257            Err(e) => Err(e)?,
258          };
259          let is_null = match is_null(bytes) {
260            Ok(is_null) => {
261              if is_null {
262                Some(4)
263              } else {
264                None
265              }
266            }
267            Err(e) => Err(e)?,
268          };
269
270          if let Some(len) = is_number.or(is_bool).or(is_null) {
271            bytes.advance(len).map_err(JsonError::BytesError)?;
272          } else {
273            Err(JsonError::InvalidValue)?;
274          }
275        }
276      }
277
278      // We now have to read past the next comma, or to the next closing of a structure
279      advance_past_comma_or_to_close(bytes)?;
280
281      Ok(result)
282    }
283  }
284}
285
286/// A deserializer for a JSON-encoded structure.
287pub struct Deserializer<'bytes, B: BytesLike<'bytes>, S: Stack> {
288  bytes: B,
289  stack: S,
290  /*
291    We advance the deserializer within `Drop` which cannot return an error. If an error is raised
292    within drop, we store it here to be consumed upon the next call to a method which can return an
293    error (if one is ever called).
294  */
295  error: Option<JsonError<'bytes, B, S>>,
296}
297
298/// A JSON value.
299// Internally, we assume whenever this is held, the top item on the stack is `State::Unknown`
300pub struct Value<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> {
301  deserializer: Option<&'parent mut Deserializer<'bytes, B, S>>,
302}
303
304impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Drop for Value<'bytes, 'parent, B, S> {
305  fn drop(&mut self) {
306    /*
307      When this value is dropped, we advance the deserializer past it if it hasn't already been
308      converted into a `FieldIterator` or `ArrayIterator` (which each have their own `Drop`
309      implementations).
310    */
311    if let Some(deserializer) = self.deserializer.take() {
312      if deserializer.error.is_some() {
313        return;
314      }
315
316      let Some(current) = deserializer.stack.peek() else {
317        deserializer.error = Some(JsonError::InternalError);
318        return;
319      };
320
321      let mut depth = match current {
322        State::Object | State::Array => 1,
323        State::Unknown => {
324          let step = match single_step(&mut deserializer.bytes, &mut deserializer.stack) {
325            Ok(SingleStepResult::Unknown(step)) => step,
326            Ok(_) => {
327              deserializer.error = Some(JsonError::InternalError);
328              return;
329            }
330            Err(e) => {
331              deserializer.error = Some(e);
332              return;
333            }
334          };
335          match step {
336            // We successfully advanced past this item
337            SingleStepUnknownResult::String(_) | SingleStepUnknownResult::Advanced => return,
338            // We opened an object/array we now have to advance past
339            SingleStepUnknownResult::ObjectOpened | SingleStepUnknownResult::ArrayOpened => 1,
340          }
341        }
342      };
343
344      // Since our object isn't a unit, step the deserializer until it's advanced past
345      while depth != 0 {
346        let step = match single_step(&mut deserializer.bytes, &mut deserializer.stack) {
347          Ok(step) => step,
348          Err(e) => {
349            deserializer.error = Some(e);
350            return;
351          }
352        };
353        match step {
354          SingleStepResult::Object(SingleStepObjectResult::Closed) |
355          SingleStepResult::Array(SingleStepArrayResult::Closed) => depth -= 1,
356          SingleStepResult::Unknown(
357            SingleStepUnknownResult::ObjectOpened | SingleStepUnknownResult::ArrayOpened,
358          ) => depth += 1,
359          _ => {}
360        }
361      }
362    }
363  }
364}
365
366impl<'bytes, B: BytesLike<'bytes>, S: Stack> Deserializer<'bytes, B, S> {
367  /// Create a new deserializer.
368  pub fn new(mut bytes: B) -> Result<Self, JsonError<'bytes, B, S>> {
369    advance_whitespace(&mut bytes)?;
370
371    let mut stack = S::empty();
372    stack.push(State::Unknown).map_err(JsonError::StackError)?;
373
374    Ok(Deserializer { bytes, stack, error: None })
375  }
376
377  /// Obtain the `Value` representing the serialized structure.
378  ///
379  /// This takes a mutable reference as `Deserializer` is the owned object representing the
380  /// deserializer's state. However, this is not eligible to be called more than once, even after
381  /// the initial mutable borrow is dropped. Multiple calls to this function will cause an error to
382  /// be returned.
383  #[inline(always)]
384  pub fn value(&mut self) -> Result<Value<'bytes, '_, B, S>, JsonError<'bytes, B, S>> {
385    if self.stack.depth() != 1 {
386      Err(JsonError::ReusedDeserializer)?;
387    }
388    let result = Value { deserializer: Some(self) };
389    if !(result.is_object()? || result.is_array()?) {
390      Err(JsonError::TypeError)?;
391    }
392    Ok(result)
393  }
394}
395
396/// An iterator over fields.
397pub struct FieldIterator<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> {
398  deserializer: &'parent mut Deserializer<'bytes, B, S>,
399  done: bool,
400}
401
402// When this object is dropped, advance the decoder past the unread items
403impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Drop
404  for FieldIterator<'bytes, 'parent, B, S>
405{
406  #[inline(always)]
407  fn drop(&mut self) {
408    if self.deserializer.error.is_some() {
409      return;
410    }
411
412    loop {
413      let Some(next) = self.next() else { break };
414      let next = next.map(|_| ());
415      match next {
416        Ok(()) => {}
417        Err(e) => {
418          self.deserializer.error = Some(e);
419          break;
420        }
421      }
422    }
423  }
424}
425
426impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> FieldIterator<'bytes, 'parent, B, S> {
427  /// The next entry (key, value) within the object.
428  ///
429  /// The key is presented as an iterator over the characters within the serialized string, with
430  /// the escape sequences handled. If the key specifies invalid UTF characters, the iterator will
431  /// yield an error when it attempts to parse them. While it may not be possible to parse a key
432  /// as UTF characters, decoding of this field's value (and the rest of the structure) is still
433  /// possible (even _after_ the iterator yields its error). For more information, please refer to
434  /// [`Value::to_str`].
435  ///
436  /// This is approximate to `Iterator::next` yet each item maintains a mutable reference to the
437  /// iterator. Accordingly, we cannot use `Iterator::next` which requires items not borrow from
438  /// the iterator.
439  ///
440  /// [polonius-the-crab](https://docs.rs/polonius-the-crab) details a frequent limitation of
441  /// Rust's borrow checker which users of this function may incur. It also details potential
442  /// solutions (primarily using inlined code instead of functions, callbacks) before presenting
443  /// itself as a complete solution. Please refer to it if you have difficulties calling this
444  /// method for context.
445  #[allow(clippy::type_complexity, clippy::should_implement_trait)]
446  pub fn next(
447    &mut self,
448  ) -> Option<
449    Result<
450      (
451        impl use<'bytes, B, S> + Iterator<Item = Result<char, JsonError<'bytes, B, S>>>,
452        Value<'bytes, '_, B, S>,
453      ),
454      JsonError<'bytes, B, S>,
455    >,
456  > {
457    if let Some(err) = self.deserializer.error {
458      return Some(Err(err));
459    }
460
461    if self.done {
462      None?;
463    }
464
465    loop {
466      let result = match single_step(&mut self.deserializer.bytes, &mut self.deserializer.stack) {
467        Ok(SingleStepResult::Object(result)) => result,
468        Ok(_) => break Some(Err(JsonError::InternalError)),
469        Err(e) => break Some(Err(e)),
470      };
471      match result {
472        SingleStepObjectResult::Field { key } => {
473          break Some(Ok((
474            UnescapeString::from(key),
475            Value { deserializer: Some(self.deserializer) },
476          )))
477        }
478        SingleStepObjectResult::Closed => {
479          self.done = true;
480          None?
481        }
482      }
483    }
484  }
485}
486
487/// An iterator over an array.
488pub struct ArrayIterator<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> {
489  deserializer: &'parent mut Deserializer<'bytes, B, S>,
490  done: bool,
491}
492
493// When this array is dropped, advance the decoder past the unread items
494impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Drop
495  for ArrayIterator<'bytes, 'parent, B, S>
496{
497  #[inline(always)]
498  fn drop(&mut self) {
499    if self.deserializer.error.is_some() {
500      return;
501    }
502
503    loop {
504      let Some(next) = self.next() else { break };
505      let next = next.map(|_| ());
506      match next {
507        Ok(()) => {}
508        Err(e) => {
509          self.deserializer.error = Some(e);
510          break;
511        }
512      }
513    }
514  }
515}
516
517impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> ArrayIterator<'bytes, 'parent, B, S> {
518  /// The next item within the array.
519  ///
520  /// This is approximate to `Iterator::next` yet each item maintains a mutable reference to the
521  /// iterator. Accordingly, we cannot use `Iterator::next` which requires items not borrow from
522  /// the iterator.
523  ///
524  /// [polonius-the-crab](https://docs.rs/polonius-the-crab) details a frequent limitation of
525  /// Rust's borrow checker which users of this function may incur. It also details potential
526  /// solutions (primarily using inlined code instead of functions, callbacks) before presenting
527  /// itself as a complete solution. Please refer to it if you have difficulties calling this
528  /// method for context.
529  #[allow(clippy::should_implement_trait)]
530  pub fn next(&mut self) -> Option<Result<Value<'bytes, '_, B, S>, JsonError<'bytes, B, S>>> {
531    if let Some(err) = self.deserializer.error {
532      return Some(Err(err));
533    }
534
535    if self.done {
536      None?;
537    }
538
539    loop {
540      let result = match single_step(&mut self.deserializer.bytes, &mut self.deserializer.stack) {
541        Ok(SingleStepResult::Array(result)) => result,
542        Ok(_) => break Some(Err(JsonError::InternalError)),
543        Err(e) => break Some(Err(e)),
544      };
545      match result {
546        SingleStepArrayResult::Value => {
547          break Some(Ok(Value { deserializer: Some(self.deserializer) }))
548        }
549        SingleStepArrayResult::Closed => {
550          self.done = true;
551          None?
552        }
553      }
554    }
555  }
556}
557
558impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Value<'bytes, 'parent, B, S> {
559  /// Check if the current item is an object.
560  #[inline(always)]
561  pub fn is_object(&self) -> Result<bool, JsonError<'bytes, B, S>> {
562    Ok(
563      self
564        .deserializer
565        .as_ref()
566        .ok_or(JsonError::InternalError)?
567        .bytes
568        .peek(0)
569        .map_err(JsonError::BytesError)? ==
570        b'{',
571    )
572  }
573
574  /// Iterate over the fields within this object.
575  ///
576  /// If a field is present multiple times, this will yield each instance.
577  pub fn fields(mut self) -> Result<FieldIterator<'bytes, 'parent, B, S>, JsonError<'bytes, B, S>> {
578    let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
579    if let Some(err) = deserializer.error {
580      Err(err)?;
581    }
582
583    match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
584      SingleStepResult::Unknown(SingleStepUnknownResult::ObjectOpened) => {
585        Ok(FieldIterator { deserializer, done: false })
586      }
587      _ => Err(JsonError::TypeError),
588    }
589  }
590
591  /// Check if the current item is an array.
592  #[inline(always)]
593  pub fn is_array(&self) -> Result<bool, JsonError<'bytes, B, S>> {
594    Ok(
595      self
596        .deserializer
597        .as_ref()
598        .ok_or(JsonError::InternalError)?
599        .bytes
600        .peek(0)
601        .map_err(JsonError::BytesError)? ==
602        b'[',
603    )
604  }
605
606  /// Iterate over all items within this container.
607  pub fn iterate(
608    mut self,
609  ) -> Result<ArrayIterator<'bytes, 'parent, B, S>, JsonError<'bytes, B, S>> {
610    let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
611    if let Some(err) = deserializer.error {
612      Err(err)?;
613    }
614
615    match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
616      SingleStepResult::Unknown(SingleStepUnknownResult::ArrayOpened) => {
617        Ok(ArrayIterator { deserializer, done: false })
618      }
619      _ => Err(JsonError::TypeError),
620    }
621  }
622
623  /// Check if the current item is a string.
624  #[inline(always)]
625  pub fn is_str(&self) -> Result<bool, JsonError<'bytes, B, S>> {
626    Ok(
627      self
628        .deserializer
629        .as_ref()
630        .ok_or(JsonError::InternalError)?
631        .bytes
632        .peek(0)
633        .map_err(JsonError::BytesError)? ==
634        b'"',
635    )
636  }
637
638  /// Get the current item as a 'string'.
639  ///
640  /// As we cannot perform allocations, we do not yield a [`alloc::string::String`] but rather an
641  /// iterator for the contents of the serialized string (with its escape sequences handled). This
642  /// may be converted to an `String` with `.collect::<Result<String, _>>()?`.
643  ///
644  /// RFC 8259 allows strings to specify invalid UTF-8 codepoints. This library supports working
645  /// with such values, as required to be compliant with RFC 8259, but this function's return value
646  /// will error when attempting to return a non-UTF-8 value. Please keep this subtlety in mind.
647  #[inline(always)]
648  pub fn to_str(
649    mut self,
650  ) -> Result<
651    impl use<'bytes, B, S> + Iterator<Item = Result<char, JsonError<'bytes, B, S>>>,
652    JsonError<'bytes, B, S>,
653  > {
654    let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
655    match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
656      SingleStepResult::Unknown(SingleStepUnknownResult::String(str)) => {
657        Ok(UnescapeString::from(str))
658      }
659      _ => Err(JsonError::TypeError),
660    }
661  }
662
663  /// Get the current item as an `i64`.
664  ///
665  /// This uses the definition of a number defined in RFC 8259, then constrains it to having no
666  /// fractional, exponent parts. Then, it's yielded if it's representable within an `i64`.
667  ///
668  /// This is _exact_. It does not go through `f64` and does not experience its approximations.
669  #[inline(always)]
670  pub fn as_i64(&self) -> Result<i64, JsonError<'bytes, B, S>> {
671    let bytes = &self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes;
672
673    let (i, str) = number::as_number_str(bytes)?;
674    let str = core::str::from_utf8(&str[.. i]).map_err(|_| JsonError::InternalError)?;
675    if str.contains('.') || str.contains('e') || str.contains('E') {
676      Err(JsonError::TypeError)?;
677    }
678    <i64 as core::str::FromStr>::from_str(str).map_err(|_| JsonError::TypeError)
679  }
680
681  /// Get the current item as an `f64`.
682  #[inline(always)]
683  pub fn as_f64(&self) -> Result<f64, JsonError<'bytes, B, S>> {
684    Ok(number::as_number(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)?.1)
685  }
686
687  /// Get the current item as a `bool`.
688  #[inline(always)]
689  pub fn as_bool(&self) -> Result<bool, JsonError<'bytes, B, S>> {
690    as_bool(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)
691  }
692
693  /// Check if the current item is `null`.
694  #[inline(always)]
695  pub fn is_null(&self) -> Result<bool, JsonError<'bytes, B, S>> {
696    is_null(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)
697  }
698}