use crate::numberparse::Number;
use crate::*;
use serde_ext::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};
use serde_ext::forward_to_deserialize_any;
impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline(always))]
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match stry!(self.next()) {
b'"' => {
visitor.visit_borrowed_str(stry!(self.parse_str_()))
}
b'n' => visitor.visit_unit(),
b't' => visitor.visit_bool(true),
b'f' => visitor.visit_bool(false),
b'-' => match stry!(self.parse_number(true)) {
Number::F64(n) => visitor.visit_f64(n),
Number::I64(n) => visitor.visit_i64(n),
},
b'0'..=b'9' => match stry!(self.parse_number(false)) {
Number::F64(n) => visitor.visit_f64(n),
Number::I64(n) => visitor.visit_i64(n),
},
b'[' => visitor.visit_seq(CommaSeparated::new(&mut self)),
b'{' => visitor.visit_map(CommaSeparated::new(&mut self)),
_c => Err(self.error(ErrorType::UnexpectedCharacter)),
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match stry!(self.next()) {
b't' => visitor.visit_bool(true),
b'f' => visitor.visit_bool(false),
_c => Err(self.error(ErrorType::ExpectedBoolean)),
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if stry!(self.next()) != b'"' {
return Err(self.error(ErrorType::ExpectedString));
}
if let Some(next) = self.structural_indexes.get(self.idx + 1) {
if *next as usize - self.iidx < 32 {
return visitor.visit_borrowed_str(stry!(self.parse_str_()));
}
}
visitor.visit_borrowed_str(stry!(self.parse_str_()))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if stry!(self.next()) != b'"' {
return Err(self.error(ErrorType::ExpectedString));
}
if let Some(next) = self.structural_indexes.get(self.idx + 1) {
if *next as usize - self.iidx < 32 {
return visitor.visit_str(stry!(self.parse_str_()));
}
}
visitor.visit_str(stry!(self.parse_str_()))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let v: i64 = stry!(self.parse_signed());
visitor.visit_i8(v as i8)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let v: i64 = stry!(self.parse_signed());
visitor.visit_i16(v as i16)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let v: i64 = stry!(self.parse_signed());
visitor.visit_i32(v as i32)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i64(stry!(self.parse_signed()))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let v: u64 = stry!(self.parse_unsigned());
visitor.visit_u8(v as u8)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let v: u64 = stry!(self.parse_unsigned());
visitor.visit_u16(v as u16)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let v: u64 = stry!(self.parse_unsigned());
visitor.visit_u32(v as u32)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u64(stry!(self.parse_unsigned()))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let v: f64 = stry!(self.parse_double());
visitor.visit_f32(v as f32)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_f64(stry!(self.parse_double()))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if stry!(self.peek()) == b'n' {
self.skip();
visitor.visit_unit()
} else {
visitor.visit_some(self)
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if stry!(self.next()) != b'n' {
return Err(self.error(ErrorType::ExpectedNull));
}
visitor.visit_unit()
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if stry!(self.next()) == b'[' {
visitor.visit_seq(CommaSeparated::new(&mut self))
} else {
Err(self.error(ErrorType::ExpectedArray))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let r = self.deserialize_seq(visitor);
self.skip();
r
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if stry!(self.next()) == b'{' {
visitor.visit_map(CommaSeparated::new(&mut self))
} else {
Err(self.error(ErrorType::ExpectedMap))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_map(visitor)
}
forward_to_deserialize_any! {
i128 u128 char
bytes byte_buf
enum identifier ignored_any
}
}
struct CommaSeparated<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
first: bool,
len: usize,
}
impl<'a, 'de> CommaSeparated<'a, 'de> {
#[cfg_attr(not(feature = "no-inline"), inline)]
fn new(de: &'a mut Deserializer<'de>) -> Self {
CommaSeparated {
first: true,
len: de.count_elements(),
de,
}
}
}
impl<'de, 'a> SeqAccess<'de> for CommaSeparated<'a, 'de> {
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
if self.len == 0 {
self.de.skip();
Ok(None)
} else {
if !self.first {
self.de.skip();
} else {
self.first = false;
}
self.len -= 1;
seed.deserialize(&mut *self.de).map(Some)
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn size_hint(&self) -> Option<usize> {
Some(self.len)
}
}
impl<'de, 'a> MapAccess<'de> for CommaSeparated<'a, 'de> {
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'de>,
{
if self.len == 0 {
if self.first {
self.de.skip();
}
Ok(None)
} else {
self.len -= 1;
self.first = false;
seed.deserialize(&mut *self.de).map(Some)
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'de>,
{
self.de.skip();
let r = seed.deserialize(&mut *self.de);
self.de.skip();
r
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn size_hint(&self) -> Option<usize> {
Some(self.len)
}
}