#[cfg(feature = "span")]
use super::span::*;
use core::{
alloc::Layout,
fmt::{self, Debug, Display, Formatter},
hint::unreachable_unchecked,
ops::{Deref, DerefMut},
ptr::dangling_mut,
slice::from_raw_parts,
str::from_utf8_unchecked,
};
use std::alloc::{alloc, realloc};
use serde::{
Deserialize, Deserializer,
de::{self, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor},
forward_to_deserialize_any,
};
use crate::{
Parser,
config::Config,
misc::{ESC_LUT, NUM_LUT},
source::{Source, Volatility},
};
type Result<T> = core::result::Result<T, Error>;
#[repr(transparent)]
pub struct Unchecked<'a, 'de, S: Source, C: Config>(pub &'a mut Parser<'de, S, C>);
impl<S: Source, C: Config> Unchecked<'_, '_, S, C> {
fn skip_whitespace_alt(&mut self) {
loop {
self.inc(1);
let tmp = self.cur();
if !matches!(tmp, b' ' | b'\t' | b'\n' | b'\r') {
return;
}
}
}
unsafe fn parse_literal<'a, V: Visitor<'a>>(&mut self, visitor: V) -> Result<V::Value> {
if S::Volatility::IS_VOLATILE {
let tmp = self.idx().wrapping_add(1);
self.src.trim(tmp);
}
let tmp = self.skip_whitespace();
if NUM_LUT[tmp as usize] {
let neg = tmp == b'-';
if neg {
self.inc(1)
}
let start = self.idx();
let (val, is_int) = self.parse_u64();
'int: {
if is_int {
self.dec();
return if neg {
if val > 9223372036854775808 {
break 'int;
}
visitor.visit_i64(val.wrapping_neg() as _)
} else {
visitor.visit_u64(val)
};
}
}
return visitor.visit_f64(self.parse_f64(val, neg, start).unwrap_unchecked());
}
let tmp = match self.cur() {
b'n' => visitor.visit_unit(),
c => {
let val = c == b't';
self.inc(!val as _);
visitor.visit_bool(val)
}
};
self.inc(3);
tmp
}
}
macro_rules! deserialize_literal {
($($name:ident),* $(,)?) => {
$(
fn $name<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
unsafe { self.parse_literal(visitor) }
}
)*
}
}
impl<'de, S: Source, C: Config> Deserializer<'de> for &mut Unchecked<'_, 'de, S, C> {
type Error = Error;
fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
let tmp = self.skip_whitespace();
self.dec();
match tmp {
b'"' => self.deserialize_str(visitor),
b'{' => self.deserialize_map(visitor),
b'[' => self.deserialize_seq(visitor),
_ => unsafe { self.parse_literal(visitor) },
}
}
fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
self.deserialize_str(visitor)
}
fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
self.skip_whitespace();
if S::Volatility::IS_VOLATILE {
let tmp = self.idx();
self.src.trim(tmp);
}
if !S::Volatility::IS_VOLATILE & S::INSITU {
let start = unsafe { self.cur_ptr_mut().add(1) };
let mut offset = start;
let mut len = 0;
loop {
if self.simd_str_unchecked() {
continue;
}
self.inc(1);
break match self.cur() {
b'"' => unsafe {
let count = self.cur_ptr().offset_from_unsigned(offset);
if len != 0 {
start.add(len).copy_from(offset, count);
}
len += count;
let tmp = from_raw_parts(start, len);
visitor.visit_borrowed_str(from_utf8_unchecked(tmp))
},
b'\\' => unsafe {
let count = self.cur_ptr().offset_from_unsigned(offset);
start.add(len).copy_from(offset, count);
self.inc(1);
len += count;
offset = self.cur_ptr_mut().add(1);
let ptr = start.add(len);
let tmp = self.cur();
let esc = ESC_LUT[tmp as usize];
if esc != 0 {
ptr.write(esc);
len += 1;
continue;
}
let mut tmp = [0; 4];
let esc = self.unicode_escape(&mut tmp).unwrap_unchecked();
ptr.copy_from_nonoverlapping(esc.as_ptr(), esc.len());
offset = self.cur_ptr_mut().add(1);
len += esc.len();
continue;
},
_ => continue,
};
}
} else if !S::Volatility::IS_VOLATILE & !S::INSITU {
let mut offset = unsafe { self.cur_ptr().add(1) };
let mut buf = dangling_mut();
let mut cap = 0;
let mut len = 0;
loop {
if self.simd_str_unchecked() {
continue;
}
self.inc(1);
match self.cur() {
b'"' => break,
b'\\' => unsafe {
let count = self.cur_ptr().offset_from_unsigned(offset);
let new_len = len + count + 4;
if cap < new_len {
let tmp = new_len * 5 / 4;
let layout = Layout::array::<u8>(tmp).unwrap_unchecked();
buf = if cap != 0 {
realloc(
buf,
Layout::array::<u8>(cap).unwrap_unchecked(),
layout.size(),
)
} else {
alloc(layout)
};
cap = tmp;
}
buf.add(len).copy_from_nonoverlapping(offset, count);
self.inc(1);
len += count;
offset = self.cur_ptr().add(1);
let tmp = self.cur();
let buf = buf.add(len);
let esc = ESC_LUT[tmp as usize];
if esc != 0 {
buf.write(esc);
len += 1;
continue;
}
let mut tmp = [0; 4];
let esc = self.unicode_escape(&mut tmp).unwrap_unchecked();
buf.copy_from_nonoverlapping(esc.as_ptr(), esc.len());
offset = self.cur_ptr().add(1);
len += esc.len();
continue;
},
_ => continue,
};
}
if len == 0 {
return unsafe {
visitor.visit_borrowed_str(from_utf8_unchecked(from_raw_parts(
offset,
self.cur_ptr().offset_from_unsigned(offset),
)))
};
}
let count = unsafe { self.cur_ptr().offset_from_unsigned(offset) };
let new_len = len + count;
if cap < new_len {
buf = unsafe {
realloc(
buf,
Layout::array::<u8>(cap).unwrap_unchecked(),
Layout::array::<u8>(new_len).unwrap_unchecked().size(),
)
};
cap = new_len;
}
unsafe {
buf.add(len).copy_from_nonoverlapping(offset, count);
visitor.visit_string(String::from_raw_parts(buf, new_len, cap))
}
} else {
let mut offset = self.idx() + 1;
let mut buf = dangling_mut();
let mut cap = 0;
let mut len = 0;
loop {
if self.simd_str_unchecked() {
continue;
}
self.inc(1);
match self.cur() {
b'"' => break,
b'\\' => unsafe {
let count = self.idx() - offset;
let new_len = len + count + 4;
if cap < new_len {
let tmp = new_len * 5 / 4;
let layout = Layout::array::<u8>(tmp).unwrap_unchecked();
buf = if cap != 0 {
realloc(
buf,
Layout::array::<u8>(cap).unwrap_unchecked(),
layout.size(),
)
} else {
alloc(layout)
};
cap = tmp;
}
buf.add(len)
.copy_from_nonoverlapping(self.src.ptr(offset), count);
self.inc(1);
len += count;
offset = self.idx() + 1;
let tmp = self.cur();
let buf = buf.add(len);
let esc = ESC_LUT[tmp as usize];
if esc != 0 {
buf.write(esc);
len += 1;
continue;
}
let mut tmp = [0; 4];
let esc = self.unicode_escape(&mut tmp).unwrap_unchecked();
buf.copy_from_nonoverlapping(esc.as_ptr(), esc.len());
offset = self.idx() + 1;
len += esc.len();
continue;
},
_ => continue,
};
}
let count = self.idx() - offset;
let new_len = len + count;
if cap < new_len {
buf = unsafe {
let layout = Layout::array::<u8>(new_len).unwrap_unchecked();
if cap == 0 {
alloc(layout)
} else {
realloc(
buf,
Layout::array::<u8>(cap).unwrap_unchecked(),
layout.size(),
)
}
};
cap = new_len;
}
unsafe {
buf.add(len)
.copy_from_nonoverlapping(self.src.ptr(offset), count);
visitor.visit_string(String::from_raw_parts(buf, new_len, cap))
}
}
}
fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
self.deserialize_str(visitor)
}
fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
match self.skip_whitespace() {
b'n' => {
self.inc(3);
visitor.visit_none()
}
_ => {
self.dec();
visitor.visit_some(self)
}
}
}
fn deserialize_unit_struct<V: Visitor<'de>>(
self,
_: &'static str,
visitor: V,
) -> Result<V::Value> {
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V: Visitor<'de>>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value> {
match name {
#[cfg(feature = "span")]
TOKEN => unsafe { Ok(visitor.visit_seq(Builder::new(self)).unwrap_unchecked()) },
_ => visitor.visit_newtype_struct(self),
}
}
fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
if S::Volatility::IS_VOLATILE {
let tmp = self.idx().wrapping_add(1);
self.src.trim(tmp);
}
self.skip_whitespace();
let tmp = visitor.visit_seq(&mut *self);
self.skip_whitespace_alt();
tmp
}
fn deserialize_tuple<V: Visitor<'de>>(self, _: usize, visitor: V) -> Result<V::Value> {
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V: Visitor<'de>>(
self,
_: &'static str,
_: usize,
visitor: V,
) -> Result<V::Value> {
self.deserialize_seq(visitor)
}
fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
if S::Volatility::IS_VOLATILE {
let tmp = self.idx().wrapping_add(1);
self.src.trim(tmp);
}
self.skip_whitespace();
visitor.visit_map(self)
}
fn deserialize_struct<V: Visitor<'de>>(
self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value> {
match self.skip_whitespace() {
b'{' => visitor.visit_map(self),
b'[' => {
let tmp = visitor.visit_seq(&mut *self);
self.skip_whitespace_alt();
tmp
}
_ => unsafe { unreachable_unchecked() },
}
}
fn deserialize_enum<V: Visitor<'de>>(
self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value> {
match self.skip_whitespace() {
b'{' => {
let tmp = visitor.visit_enum(&mut *self);
self.skip_whitespace();
tmp
}
b'"' => visitor.visit_enum(UnitVariantAccess(self)),
_ => unsafe { unreachable_unchecked() },
}
}
fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
self.deserialize_str(visitor)
}
fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
self.skip_value_unchecked();
visitor.visit_unit()
}
forward_to_deserialize_any! {
bytes byte_buf
}
deserialize_literal! {
deserialize_i8,
deserialize_i16,
deserialize_i32,
deserialize_i64,
deserialize_u8,
deserialize_u16,
deserialize_u32,
deserialize_u64,
deserialize_f32,
deserialize_f64,
deserialize_bool,
deserialize_unit,
}
}
impl<'de, S: Source, C: Config> MapAccess<'de> for Unchecked<'_, 'de, S, C> {
type Error = Error;
fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
loop {
return Ok(match self.skip_whitespace() {
b'"' => unsafe {
self.dec();
Some(seed.deserialize(self).unwrap_unchecked())
},
b',' => continue,
b'}' => None,
_ => unsafe { unreachable_unchecked() },
});
}
}
fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
self.skip_whitespace();
seed.deserialize(self)
}
}
impl<'de, S: Source, C: Config> SeqAccess<'de> for Unchecked<'_, 'de, S, C> {
type Error = Error;
fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>> {
loop {
return Ok(match self.skip_whitespace() {
b',' => continue,
b']' => {
self.dec();
None
}
_ => unsafe {
self.dec();
Some(seed.deserialize(self).unwrap_unchecked())
},
});
}
}
}
impl<'de, S: Source, C: Config> EnumAccess<'de> for &mut Unchecked<'_, 'de, S, C> {
type Error = Error;
type Variant = Self;
fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant)> {
unsafe {
let tmp = seed.deserialize(&mut *self.0).unwrap_unchecked();
self.skip_whitespace();
Ok((tmp, self))
}
}
}
impl<'de, S: Source, C: Config> VariantAccess<'de> for &mut Unchecked<'_, 'de, S, C> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Deserialize::deserialize(self)
}
fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
seed.deserialize(self)
}
fn tuple_variant<V: Visitor<'de>>(self, _: usize, visitor: V) -> Result<V::Value> {
Deserializer::deserialize_seq(self, visitor)
}
fn struct_variant<V: Visitor<'de>>(
self,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value> {
Deserializer::deserialize_struct(self, "", fields, visitor)
}
}
struct UnitVariantAccess<'a, 'de, S: Source, C: Config>(&'a mut Parser<'de, S, C>);
impl<'a, 'de, S: Source, C: Config> EnumAccess<'de> for UnitVariantAccess<'a, 'de, S, C> {
type Error = Error;
type Variant = Self;
fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self)> {
unsafe {
self.0.dec();
Ok((seed.deserialize(&mut *self.0).unwrap_unchecked(), self))
}
}
}
impl<'a, 'de, S: Source, C: Config> de::VariantAccess<'de> for UnitVariantAccess<'a, 'de, S, C> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, _: T) -> Result<T::Value> {
unsafe { unreachable_unchecked() }
}
fn tuple_variant<V: Visitor<'de>>(self, _: usize, _: V) -> Result<V::Value> {
unsafe { unreachable_unchecked() }
}
fn struct_variant<V: Visitor<'de>>(self, _: &'static [&'static str], _: V) -> Result<V::Value> {
unsafe { unreachable_unchecked() }
}
}
pub struct Error;
impl Debug for Error {
fn fmt(&self, _: &mut Formatter<'_>) -> fmt::Result {
Ok(())
}
}
impl Display for Error {
fn fmt(&self, _: &mut Formatter<'_>) -> fmt::Result {
Ok(())
}
}
impl de::Error for Error {
fn custom<T: Display>(_: T) -> Self {
Self
}
}
impl core::error::Error for Error {}
impl<'de, S: Source, C: Config> Deref for Unchecked<'_, 'de, S, C> {
type Target = Parser<'de, S, C>;
#[inline(always)]
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<S: Source, C: Config> DerefMut for Unchecked<'_, '_, S, C> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
self.0
}
}