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
426#[rustfmt::skip]
427impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack>
428  FieldIterator<'bytes, 'parent, B, S>
429{
430  /// The next entry (key, value) within the object.
431  ///
432  /// This is approximate to `Iterator::next` yet each item maintains a mutable reference to the
433  /// iterator. Accordingly, we cannot use `Iterator::next` which requires items not borrow from
434  /// the iterator.
435  ///
436  /// [polonius-the-crab](https://docs.rs/polonius-the-crab) details a frequent limitation of
437  /// Rust's borrow checker which users of this function may incur. It also details potential
438  /// solutions (primarily using inlined code instead of functions, callbacks) before presenting
439  /// itself as a complete solution. Please refer to it if you have difficulties calling this
440  /// method for context.
441  #[allow(clippy::type_complexity, clippy::should_implement_trait)]
442  pub fn next(
443    &mut self,
444  ) -> Option<Result<(String<'bytes, B>, Value<'bytes, '_, B, S>), JsonError<'bytes, B, S>>>
445  {
446    if let Some(err) = self.deserializer.error {
447      return Some(Err(err));
448    }
449
450    if self.done {
451      None?;
452    }
453
454    loop {
455      let result = match single_step(&mut self.deserializer.bytes, &mut self.deserializer.stack) {
456        Ok(SingleStepResult::Object(result)) => result,
457        Ok(_) => break Some(Err(JsonError::InternalError)),
458        Err(e) => break Some(Err(e)),
459      };
460      match result {
461        SingleStepObjectResult::Field { key } => {
462          break Some(Ok((key, Value { deserializer: Some(self.deserializer) })))
463        }
464        SingleStepObjectResult::Closed => {
465          self.done = true;
466          None?
467        }
468      }
469    }
470  }
471}
472
473/// An iterator over an array.
474pub struct ArrayIterator<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> {
475  deserializer: &'parent mut Deserializer<'bytes, B, S>,
476  done: bool,
477}
478
479// When this array is dropped, advance the decoder past the unread items
480impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Drop
481  for ArrayIterator<'bytes, 'parent, B, S>
482{
483  #[inline(always)]
484  fn drop(&mut self) {
485    if self.deserializer.error.is_some() {
486      return;
487    }
488
489    loop {
490      let Some(next) = self.next() else { break };
491      let next = next.map(|_| ());
492      match next {
493        Ok(()) => {}
494        Err(e) => {
495          self.deserializer.error = Some(e);
496          break;
497        }
498      }
499    }
500  }
501}
502
503impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> ArrayIterator<'bytes, 'parent, B, S> {
504  /// The next item within the array.
505  ///
506  /// This is approximate to `Iterator::next` yet each item maintains a mutable reference to the
507  /// iterator. Accordingly, we cannot use `Iterator::next` which requires items not borrow from
508  /// the iterator.
509  ///
510  /// [polonius-the-crab](https://docs.rs/polonius-the-crab) details a frequent limitation of
511  /// Rust's borrow checker which users of this function may incur. It also details potential
512  /// solutions (primarily using inlined code instead of functions, callbacks) before presenting
513  /// itself as a complete solution. Please refer to it if you have difficulties calling this
514  /// method for context.
515  #[allow(clippy::should_implement_trait)]
516  pub fn next(&mut self) -> Option<Result<Value<'bytes, '_, B, S>, JsonError<'bytes, B, S>>> {
517    if let Some(err) = self.deserializer.error {
518      return Some(Err(err));
519    }
520
521    if self.done {
522      None?;
523    }
524
525    loop {
526      let result = match single_step(&mut self.deserializer.bytes, &mut self.deserializer.stack) {
527        Ok(SingleStepResult::Array(result)) => result,
528        Ok(_) => break Some(Err(JsonError::InternalError)),
529        Err(e) => break Some(Err(e)),
530      };
531      match result {
532        SingleStepArrayResult::Value => {
533          break Some(Ok(Value { deserializer: Some(self.deserializer) }))
534        }
535        SingleStepArrayResult::Closed => {
536          self.done = true;
537          None?
538        }
539      }
540    }
541  }
542}
543
544impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Value<'bytes, 'parent, B, S> {
545  /// Check if the current item is an object.
546  #[inline(always)]
547  pub fn is_object(&self) -> Result<bool, JsonError<'bytes, B, S>> {
548    Ok(
549      self
550        .deserializer
551        .as_ref()
552        .ok_or(JsonError::InternalError)?
553        .bytes
554        .peek(0)
555        .map_err(JsonError::BytesError)? ==
556        b'{',
557    )
558  }
559
560  /// Iterate over the fields within this object.
561  ///
562  /// If a field is present multiple times, this will yield each instance.
563  pub fn fields(mut self) -> Result<FieldIterator<'bytes, 'parent, B, S>, JsonError<'bytes, B, S>> {
564    let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
565    if let Some(err) = deserializer.error {
566      Err(err)?;
567    }
568
569    match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
570      SingleStepResult::Unknown(SingleStepUnknownResult::ObjectOpened) => {
571        Ok(FieldIterator { deserializer, done: false })
572      }
573      _ => Err(JsonError::TypeError),
574    }
575  }
576
577  /// Check if the current item is an array.
578  #[inline(always)]
579  pub fn is_array(&self) -> Result<bool, JsonError<'bytes, B, S>> {
580    Ok(
581      self
582        .deserializer
583        .as_ref()
584        .ok_or(JsonError::InternalError)?
585        .bytes
586        .peek(0)
587        .map_err(JsonError::BytesError)? ==
588        b'[',
589    )
590  }
591
592  /// Iterate over all items within this container.
593  pub fn iterate(
594    mut self,
595  ) -> Result<ArrayIterator<'bytes, 'parent, B, S>, JsonError<'bytes, B, S>> {
596    let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
597    if let Some(err) = deserializer.error {
598      Err(err)?;
599    }
600
601    match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
602      SingleStepResult::Unknown(SingleStepUnknownResult::ArrayOpened) => {
603        Ok(ArrayIterator { deserializer, done: false })
604      }
605      _ => Err(JsonError::TypeError),
606    }
607  }
608
609  /// Check if the current item is a string.
610  #[inline(always)]
611  pub fn is_str(&self) -> Result<bool, JsonError<'bytes, B, S>> {
612    Ok(
613      self
614        .deserializer
615        .as_ref()
616        .ok_or(JsonError::InternalError)?
617        .bytes
618        .peek(0)
619        .map_err(JsonError::BytesError)? ==
620        b'"',
621    )
622  }
623
624  /// Get the current item as a 'string' (represented as a `B`).
625  ///
626  /// This will NOT de-escape the string in any way, returning a view of the bytes underlying the
627  /// serialization.
628  #[inline(always)]
629  pub fn to_str(mut self) -> Result<String<'bytes, B>, JsonError<'bytes, B, S>> {
630    let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
631    match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
632      SingleStepResult::Unknown(SingleStepUnknownResult::String(str)) => Ok(str),
633      _ => Err(JsonError::TypeError),
634    }
635  }
636
637  /// Get the current item as an `i64`.
638  ///
639  /// This uses the definition of a number defined in RFC 8259, then constrains it to having no
640  /// fractional, exponent parts. Then, it's yielded if it's representable within an `i64`.
641  ///
642  /// This is _exact_. It does not go through `f64` and does not experience its approximations.
643  #[inline(always)]
644  pub fn as_i64(&self) -> Result<i64, JsonError<'bytes, B, S>> {
645    let bytes = &self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes;
646
647    let (i, str) = number::as_number_str(bytes)?;
648    let str = core::str::from_utf8(&str[.. i]).map_err(|_| JsonError::InternalError)?;
649    if str.contains('.') || str.contains('e') || str.contains('E') {
650      Err(JsonError::TypeError)?;
651    }
652    <i64 as core::str::FromStr>::from_str(str).map_err(|_| JsonError::TypeError)
653  }
654
655  /// Get the current item as an `f64`.
656  #[inline(always)]
657  pub fn as_f64(&self) -> Result<f64, JsonError<'bytes, B, S>> {
658    Ok(number::as_number(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)?.1)
659  }
660
661  /// Get the current item as a `bool`.
662  #[inline(always)]
663  pub fn as_bool(&self) -> Result<bool, JsonError<'bytes, B, S>> {
664    as_bool(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)
665  }
666
667  /// Check if the current item is `null`.
668  #[inline(always)]
669  pub fn is_null(&self) -> Result<bool, JsonError<'bytes, B, S>> {
670    is_null(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)
671  }
672}