use std::fmt::{self, Display};
use serde::de::{self, Deserializer as _, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor};
use serde::forward_to_deserialize_any;
use crate::errors::{DEFAULT_RECURSION_LIMIT, JsonError, JsonErrorType, LinePosition};
use crate::number_decoder::{NumberAny, NumberInt};
use crate::parse::{Parser, Peek};
use crate::string_decoder::{StringDecoder, StringOutput, StringOutputType, Tape};
use crate::value::take_value_skip;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EnumError {
NotStringOrSingleKeyObject,
NotSingleKey,
}
impl Display for EnumError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::NotStringOrSingleKeyObject => "expected a string or single-key object for an enum",
Self::NotSingleKey => "expected a single-key object for an enum",
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
Syntax(JsonError),
Message(String),
Data { message: String, index: usize },
Enum { kind: EnumError, index: usize },
}
impl Error {
pub fn index(&self) -> Option<usize> {
match self {
Self::Syntax(err) => Some(err.index),
Self::Data { index, .. } | Self::Enum { index, .. } => Some(*index),
Self::Message(_) => None,
}
}
pub fn get_position(&self, data: &[u8]) -> Option<LinePosition> {
self.index().map(|index| LinePosition::find(data, index))
}
pub fn description(&self, data: &[u8]) -> String {
match self {
Self::Syntax(err) => err.description(data),
Self::Data { message, index } => format!("{message} at {}", LinePosition::find(data, *index)),
Self::Enum { kind, index } => format!("{kind} at {}", LinePosition::find(data, *index)),
Self::Message(message) => message.clone(),
}
}
fn with_index(self, index: usize) -> Self {
match self {
Self::Message(message) => Self::Data { message, index },
positioned => positioned,
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Syntax(err) => write!(f, "{err}"),
Self::Data { message, index } => write!(f, "{message} at index {index}"),
Self::Enum { kind, index } => write!(f, "{kind} at index {index}"),
Self::Message(message) => f.write_str(message),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Syntax(err) => Some(err),
Self::Data { .. } | Self::Enum { .. } | Self::Message(_) => None,
}
}
}
impl From<JsonError> for Error {
fn from(err: JsonError) -> Self {
Self::Syntax(err)
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Self::Message(msg.to_string())
}
}
pub fn from_slice<'a, T>(data: &'a [u8]) -> Result<T, Error>
where
T: serde::Deserialize<'a>,
{
let mut de = JiterDeserializer::new(data);
let result = T::deserialize(&mut de);
let value = result.map_err(|e| e.with_index(de.parser.index))?;
de.finish()?;
Ok(value)
}
pub fn from_str<'a, T>(data: &'a str) -> Result<T, Error>
where
T: serde::Deserialize<'a>,
{
from_slice(data.as_bytes())
}
#[derive(Debug)]
pub struct JiterDeserializer<'j> {
parser: Parser<'j>,
tape: Tape,
allow_inf_nan: bool,
recursion_limit: Option<usize>,
depth: usize,
}
impl<'j> JiterDeserializer<'j> {
pub fn new(data: &'j [u8]) -> Self {
Self {
parser: Parser::new(data),
tape: Tape::new(),
allow_inf_nan: false,
recursion_limit: Some(usize::from(DEFAULT_RECURSION_LIMIT)),
depth: 0,
}
}
pub fn with_allow_inf_nan(mut self) -> Self {
self.allow_inf_nan = true;
self
}
pub fn with_recursion_limit(mut self, limit: usize) -> Self {
self.recursion_limit = Some(limit);
self
}
pub fn disable_recursion_limit(mut self) -> Self {
self.recursion_limit = None;
self
}
pub fn finish(&mut self) -> Result<(), Error> {
self.parser.finish().map_err(Error::from)
}
fn enter(&mut self) -> Result<(), Error> {
self.depth += 1;
match self.recursion_limit {
Some(limit) if self.depth > limit => Err(Error::Syntax(JsonError::new(
JsonErrorType::RecursionLimitExceeded,
self.parser.index,
))),
_ => Ok(()),
}
}
fn leave(&mut self) {
self.depth -= 1;
}
fn skip_recursion_budget(&self) -> u8 {
match self.recursion_limit {
None => u8::MAX,
Some(limit) => limit.saturating_sub(self.depth).try_into().unwrap_or(u8::MAX),
}
}
}
impl<'de> de::Deserializer<'de> for &mut JiterDeserializer<'de> {
type Error = Error;
fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let peek = self.parser.peek()?;
let start = self.parser.index;
match peek {
Peek::Null => {
self.parser.consume_null()?;
visitor.visit_unit()
}
Peek::True => {
self.parser.consume_true()?;
visitor.visit_bool(true)
}
Peek::False => {
self.parser.consume_false()?;
visitor.visit_bool(false)
}
Peek::String => {
let output = self.parser.consume_string::<StringDecoder>(&mut self.tape, false)?;
visit_str_output(&output, visitor)
}
Peek::Array => {
self.enter()?;
let mut seq = JiterSeqAccess {
de: &mut *self,
first: true,
ended: false,
};
let value = visitor.visit_seq(&mut seq)?;
seq.finish()?;
self.leave();
Ok(value)
}
Peek::Object => {
self.enter()?;
let value = visitor.visit_map(JiterMapAccess {
de: &mut *self,
first: true,
})?;
self.leave();
Ok(value)
}
_ => match self
.parser
.consume_number::<NumberAny>(peek.into_inner(), self.allow_inf_nan)?
{
NumberAny::Int(int) => visit_int(int, visitor),
NumberAny::Float(f) if f.is_finite() => visitor.visit_f64(f),
NumberAny::Float(f) => visitor.visit_borrowed_str(non_finite_str(f)),
},
}
.map_err(|e| e.with_index(start))
}
fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
if self.parser.peek()? == Peek::Null {
self.parser.consume_null()?;
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_newtype_struct<V: Visitor<'de>>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error> {
visitor.visit_newtype_struct(self)
}
fn deserialize_enum<V: Visitor<'de>>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
match self.parser.peek()? {
Peek::String => visitor.visit_enum(JiterEnumAccess { de: self, unit: true }),
Peek::Object => {
self.enter()?;
let value = visitor.visit_enum(JiterEnumAccess {
de: &mut *self,
unit: false,
})?;
self.leave();
Ok(value)
}
_ => Err(Error::Enum {
kind: EnumError::NotStringOrSingleKeyObject,
index: self.parser.index,
}),
}
}
fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
deserialize_number(self, visitor)
}
fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
deserialize_number(self, visitor)
}
fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let peek = self.parser.peek()?;
let recursion_limit = self.skip_recursion_budget();
take_value_skip(
peek,
&mut self.parser,
&mut self.tape,
recursion_limit,
self.allow_inf_nan,
)?;
visitor.visit_unit()
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 char str string
bytes byte_buf unit unit_struct seq tuple tuple_struct map struct identifier
}
}
fn deserialize_number<'de, V: Visitor<'de>>(de: &mut JiterDeserializer<'de>, visitor: V) -> Result<V::Value, Error> {
let peek = de.parser.peek()?;
if peek.is_num() {
match de
.parser
.consume_number::<NumberAny>(peek.into_inner(), de.allow_inf_nan)?
{
NumberAny::Int(int) => visit_int(int, visitor),
NumberAny::Float(f) => visitor.visit_f64(f),
}
} else {
(&mut *de).deserialize_any(visitor)
}
}
fn non_finite_str(f: f64) -> &'static str {
if f.is_nan() {
"NaN"
} else if f < 0.0 {
"-Infinity"
} else {
"Infinity"
}
}
fn visit_str_output<'de, V: Visitor<'de>>(output: &StringOutput<'_, 'de>, visitor: V) -> Result<V::Value, Error> {
match &output.data {
StringOutputType::Data(s) => visitor.visit_borrowed_str(s),
StringOutputType::Tape(s) => visitor.visit_str(s),
}
}
fn visit_int<'de, V: Visitor<'de>>(int: NumberInt, visitor: V) -> Result<V::Value, Error> {
match int {
NumberInt::Int(i) => visitor.visit_i64(i),
#[cfg(feature = "num-bigint")]
NumberInt::BigInt(big) => {
use num_traits::ToPrimitive;
if let Some(i) = big.to_i128() {
visitor.visit_i128(i)
} else if let Some(u) = big.to_u128() {
visitor.visit_u128(u)
} else {
visitor.visit_f64(big.to_f64().unwrap_or(f64::NAN))
}
}
}
}
struct JiterSeqAccess<'a, 'de> {
de: &'a mut JiterDeserializer<'de>,
first: bool,
ended: bool,
}
impl JiterSeqAccess<'_, '_> {
fn step(&mut self) -> Result<Option<Peek>, Error> {
let peek = if std::mem::take(&mut self.first) {
self.de.parser.array_first()?
} else {
self.de.parser.array_step()?
};
if peek.is_none() {
self.ended = true;
}
Ok(peek)
}
fn finish(&mut self) -> Result<(), Error> {
while !self.ended {
if self.step()?.is_some() {
return Err(Error::Syntax(JsonError::new(
JsonErrorType::TrailingCharacters,
self.de.parser.index,
)));
}
}
Ok(())
}
}
impl<'de> SeqAccess<'de> for &mut JiterSeqAccess<'_, 'de> {
type Error = Error;
fn next_element_seed<T: de::DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> {
match self.step()? {
Some(_) => seed.deserialize(&mut *self.de).map(Some),
None => Ok(None),
}
}
}
struct JiterMapAccess<'a, 'de> {
de: &'a mut JiterDeserializer<'de>,
first: bool,
}
impl<'de> MapAccess<'de> for JiterMapAccess<'_, 'de> {
type Error = Error;
fn next_key_seed<K: de::DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> {
let output = if std::mem::take(&mut self.first) {
self.de.parser.object_first::<StringDecoder>(&mut self.de.tape)?
} else {
self.de.parser.object_step::<StringDecoder>(&mut self.de.tape)?
};
match output {
Some(output) => seed.deserialize(MapKeyDeserializer { key: output.data }).map(Some),
None => Ok(None),
}
}
fn next_value_seed<V: de::DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value, Self::Error> {
seed.deserialize(&mut *self.de)
}
}
struct MapKeyDeserializer<'t, 'de> {
key: StringOutputType<'t, 'de>,
}
impl MapKeyDeserializer<'_, '_> {
fn as_str(&self) -> &str {
match self.key {
StringOutputType::Tape(s) | StringOutputType::Data(s) => s,
}
}
}
macro_rules! deserialize_key_parsed {
($method:ident, $visit:ident, $ty:ty) => {
fn $method<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
match self.as_str().parse::<$ty>() {
Ok(value) => visitor.$visit(value),
Err(_) => self.deserialize_any(visitor),
}
}
};
}
impl<'de> de::Deserializer<'de> for MapKeyDeserializer<'_, 'de> {
type Error = Error;
fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
match self.key {
StringOutputType::Data(s) => visitor.visit_borrowed_str(s),
StringOutputType::Tape(s) => visitor.visit_str(s),
}
}
fn deserialize_enum<V: Visitor<'de>>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
let de: de::value::StrDeserializer<Error> = self.as_str().into_deserializer();
de.deserialize_enum(name, variants, visitor)
}
deserialize_key_parsed!(deserialize_bool, visit_bool, bool);
deserialize_key_parsed!(deserialize_i8, visit_i8, i8);
deserialize_key_parsed!(deserialize_i16, visit_i16, i16);
deserialize_key_parsed!(deserialize_i32, visit_i32, i32);
deserialize_key_parsed!(deserialize_i64, visit_i64, i64);
deserialize_key_parsed!(deserialize_i128, visit_i128, i128);
deserialize_key_parsed!(deserialize_u8, visit_u8, u8);
deserialize_key_parsed!(deserialize_u16, visit_u16, u16);
deserialize_key_parsed!(deserialize_u32, visit_u32, u32);
deserialize_key_parsed!(deserialize_u64, visit_u64, u64);
deserialize_key_parsed!(deserialize_u128, visit_u128, u128);
deserialize_key_parsed!(deserialize_f32, visit_f32, f32);
deserialize_key_parsed!(deserialize_f64, visit_f64, f64);
forward_to_deserialize_any! {
char str string bytes byte_buf option unit unit_struct newtype_struct
seq tuple tuple_struct map struct identifier ignored_any
}
}
struct JiterEnumAccess<'a, 'de> {
de: &'a mut JiterDeserializer<'de>,
unit: bool,
}
impl<'a, 'de> EnumAccess<'de> for JiterEnumAccess<'a, 'de> {
type Error = Error;
type Variant = JiterVariantAccess<'a, 'de>;
fn variant_seed<V: de::DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> {
let key = if self.unit {
self.de
.parser
.consume_string::<StringDecoder>(&mut self.de.tape, false)?
.data
} else {
let start = self.de.parser.index;
match self.de.parser.object_first::<StringDecoder>(&mut self.de.tape)? {
Some(output) => output.data,
None => {
return Err(Error::Enum {
kind: EnumError::NotSingleKey,
index: start,
});
}
}
};
let value = seed.deserialize(MapKeyDeserializer { key })?;
Ok((
value,
JiterVariantAccess {
de: self.de,
unit: self.unit,
},
))
}
}
struct JiterVariantAccess<'a, 'de> {
de: &'a mut JiterDeserializer<'de>,
unit: bool,
}
impl JiterVariantAccess<'_, '_> {
fn finish(&mut self) -> Result<(), Error> {
if self.unit {
Ok(())
} else {
match self.de.parser.object_step::<StringDecoder>(&mut self.de.tape)? {
None => Ok(()),
Some(_) => Err(Error::Enum {
kind: EnumError::NotSingleKey,
index: self.de.parser.index,
}),
}
}
}
}
impl<'de> VariantAccess<'de> for JiterVariantAccess<'_, 'de> {
type Error = Error;
fn unit_variant(mut self) -> Result<(), Self::Error> {
if self.unit {
Ok(())
} else {
<() as de::Deserialize>::deserialize(&mut *self.de)?;
self.finish()
}
}
fn newtype_variant_seed<T: de::DeserializeSeed<'de>>(mut self, seed: T) -> Result<T::Value, Self::Error> {
let value = seed.deserialize(&mut *self.de)?;
self.finish()?;
Ok(value)
}
fn tuple_variant<V: Visitor<'de>>(mut self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> {
let value = (&mut *self.de).deserialize_seq(visitor)?;
self.finish()?;
Ok(value)
}
fn struct_variant<V: Visitor<'de>>(
mut self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
let value = (&mut *self.de).deserialize_map(visitor)?;
self.finish()?;
Ok(value)
}
}