use crate::Context;
use crate::alloc::Vec;
use crate::de::Visitor;
use crate::json::parser::integer::decode_signed_full;
use crate::json::parser::{StringReference, Token};
mod private {
pub trait Sealed {}
impl Sealed for crate::json::parser::SliceParser<'_> {}
impl Sealed for crate::json::parser::MutSliceParser<'_, '_> {}
impl<'de, R> Sealed for &mut R where R: ?Sized + super::Parser<'de> {}
}
pub trait Parser<'de>: private::Sealed {
type Mut<'this>: Parser<'de>
where
Self: 'this;
type TryClone: Parser<'de>;
fn borrow_mut(&mut self) -> Self::Mut<'_>;
fn try_clone(&self) -> Option<Self::TryClone>;
#[doc(hidden)]
fn parse_string<'scratch, C>(
&mut self,
cx: C,
validate: bool,
scratch: &'scratch mut Vec<u8, C::Allocator>,
) -> Result<StringReference<'de, 'scratch>, C::Error>
where
C: Context,
{
let start = cx.mark();
let actual = self.lex(cx);
if !matches!(actual, Token::String) {
return Err(cx.message_at(&start, format_args!("Expected string, found {actual}")));
}
self.skip(cx, 1)?;
self.parse_string_inner(cx, validate, scratch, &start)
}
#[doc(hidden)]
fn parse_string_inner<'scratch, C>(
&mut self,
cx: C,
validate: bool,
scratch: &'scratch mut Vec<u8, C::Allocator>,
start: &C::Mark,
) -> Result<StringReference<'de, 'scratch>, C::Error>
where
C: Context;
#[doc(hidden)]
fn skip_string_inner<C>(&mut self, cx: C) -> Result<(), C::Error>
where
C: Context;
#[doc(hidden)]
fn read_byte<C>(&mut self, cx: C) -> Result<u8, C::Error>
where
C: Context,
{
let mut byte = [0];
self.read(cx, &mut byte[..])?;
let [b] = byte;
Ok(b)
}
#[doc(hidden)]
fn skip<C>(&mut self, cx: C, n: usize) -> Result<(), C::Error>
where
C: Context;
#[doc(hidden)]
fn read<C>(&mut self, cx: C, buf: &mut [u8]) -> Result<(), C::Error>
where
C: Context;
#[doc(hidden)]
fn skip_whitespace<C>(&mut self, cx: C)
where
C: Context;
#[doc(hidden)]
fn consume_while<C>(&mut self, cx: C, m: fn(u8) -> bool) -> Result<usize, C::Error>
where
C: Context,
{
let mut c = 0;
while let Some(b) = self.peek() {
if !m(b) {
return Ok(c);
}
c += 1;
self.skip(cx, 1)?;
}
Ok(c)
}
#[doc(hidden)]
fn peek(&mut self) -> Option<u8>;
#[doc(hidden)]
fn lex<C>(&mut self, cx: C) -> Token
where
C: Context,
{
self.skip_whitespace(cx);
let Some(b) = self.peek() else {
return Token::Eof;
};
Token::from_byte(b)
}
fn parse_f32<C>(&mut self, cx: C) -> Result<f32, C::Error>
where
C: Context;
fn parse_f64<C>(&mut self, cx: C) -> Result<f64, C::Error>
where
C: Context;
#[doc(hidden)]
fn parse_exact<C>(&mut self, cx: C, exact: &str) -> Result<(), C::Error>
where
C: Context,
{
debug_assert!(exact.len() <= 5);
let mark = cx.mark();
let mut bytes = [0u8; 8];
let bytes = &mut bytes[..exact.len()];
self.read(cx, bytes)?;
if bytes != exact.as_bytes() {
return Err(cx.message_at(&mark, format_args!("Expected `{exact}`")));
}
Ok(())
}
#[doc(hidden)]
fn parse_number<C, V>(&mut self, cx: C, visitor: V) -> Result<V::Ok, V::Error>
where
C: Context,
V: Visitor<'de, C, Error = C::Error, Allocator = C::Allocator>,
{
let signed = decode_signed_full::<i128, _, _>(cx, self)?;
if signed.is_negative {
let value = match signed.compute() {
Ok(value) => value,
Err(..) => {
let value = signed.compute_float();
return visitor.visit_f64(cx, value);
}
};
if value >= i8::MIN as i128 && value <= i8::MAX as i128 {
return visitor.visit_i8(cx, value as i8);
}
if value >= i16::MIN as i128 && value <= i16::MAX as i128 {
return visitor.visit_i16(cx, value as i16);
}
if value >= i32::MIN as i128 && value <= i32::MAX as i128 {
return visitor.visit_i32(cx, value as i32);
}
if value >= i64::MIN as i128 && value <= i64::MAX as i128 {
return visitor.visit_i64(cx, value as i64);
}
if value >= isize::MIN as i128 && value <= isize::MAX as i128 {
return visitor.visit_isize(cx, value as isize);
}
visitor.visit_i128(cx, value)
} else {
let value = match signed.unsigned.compute() {
Ok(value) => value,
Err(..) => {
let value = signed.unsigned.compute_float();
return visitor.visit_f64(cx, value);
}
};
if value <= u8::MAX as u128 {
return visitor.visit_u8(cx, value as u8);
}
if value <= u16::MAX as u128 {
return visitor.visit_u16(cx, value as u16);
}
if value <= u32::MAX as u128 {
return visitor.visit_u32(cx, value as u32);
}
if value <= u64::MAX as u128 {
return visitor.visit_u64(cx, value as u64);
}
if value <= usize::MAX as u128 {
return visitor.visit_usize(cx, value as usize);
}
visitor.visit_u128(cx, value)
}
}
}
impl<'de, P> Parser<'de> for &mut P
where
P: ?Sized + Parser<'de>,
{
type Mut<'this>
= P::Mut<'this>
where
Self: 'this;
type TryClone = P::TryClone;
#[inline]
fn borrow_mut(&mut self) -> Self::Mut<'_> {
(**self).borrow_mut()
}
#[inline]
fn try_clone(&self) -> Option<Self::TryClone> {
(**self).try_clone()
}
#[inline]
fn parse_string_inner<'scratch, C>(
&mut self,
cx: C,
validate: bool,
scratch: &'scratch mut Vec<u8, C::Allocator>,
start: &C::Mark,
) -> Result<StringReference<'de, 'scratch>, C::Error>
where
C: Context,
{
(**self).parse_string_inner(cx, validate, scratch, start)
}
#[inline]
fn skip_string_inner<C>(&mut self, cx: C) -> Result<(), C::Error>
where
C: Context,
{
(**self).skip_string_inner(cx)
}
#[inline]
fn read_byte<C>(&mut self, cx: C) -> Result<u8, C::Error>
where
C: Context,
{
(**self).read_byte(cx)
}
#[inline]
fn peek(&mut self) -> Option<u8> {
(**self).peek()
}
#[inline]
fn lex<C>(&mut self, cx: C) -> Token
where
C: Context,
{
(**self).lex(cx)
}
#[inline]
fn skip_whitespace<C>(&mut self, cx: C)
where
C: Context,
{
(**self).skip_whitespace(cx);
}
#[inline]
fn skip<C>(&mut self, cx: C, n: usize) -> Result<(), C::Error>
where
C: Context,
{
(**self).skip(cx, n)
}
#[inline]
fn read<C>(&mut self, cx: C, buf: &mut [u8]) -> Result<(), C::Error>
where
C: Context,
{
(**self).read(cx, buf)
}
#[inline]
fn parse_f32<C>(&mut self, cx: C) -> Result<f32, C::Error>
where
C: Context,
{
(**self).parse_f32(cx)
}
#[inline]
fn parse_f64<C>(&mut self, cx: C) -> Result<f64, C::Error>
where
C: Context,
{
(**self).parse_f64(cx)
}
}