use serde::de::IntoDeserializer;
use serde::{de, forward_to_deserialize_any};
use super::parser::{Parser, Reference};
use super::{Error, Result};
pub(crate) struct Value<'de, 'a> {
parser: &'a mut Parser<'de>,
scratch: Vec<u8>,
flat: bool,
}
impl<'de, 'a> Value<'de, 'a> {
pub(crate) fn new(parser: &'a mut Parser<'de>) -> Self {
Self {
parser,
scratch: Vec::new(),
flat: false,
}
}
pub(crate) fn new_flat(parser: &'a mut Parser<'de>) -> Self {
Self {
parser,
scratch: Vec::new(),
flat: true,
}
}
fn deserialize_number<V>(&mut self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let peek = match self.parser.peek()? {
Some(b) => b,
None => {
return Err(Error::EofReached);
}
};
let res = match peek {
b'-' => {
self.parser.discard();
self.parser.parse_integer(false)?.visit(visitor)
}
b'0'..=b'9' => self.parser.parse_integer(true)?.visit(visitor),
_ => {
return Err(Error::InvalidNumber);
}
};
match self.parser.peek()? {
None | Some(b'&') | Some(b';') => {
self.parser.discard();
res
}
Some(_) => Err(Error::InvalidNumber),
}
}
}
macro_rules! deserialize_number {
($method:ident) => {
fn $method<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
};
}
impl<'de, 'a> de::Deserializer<'de> for &mut Value<'de, 'a> {
type Error = Error;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let peek = match self.parser.peek()? {
Some(b) => b,
None => return visitor.visit_unit(),
};
let value = match peek {
b'=' => Err(Error::InvalidMapKey),
_ => match self.parser.parse_str(&mut self.scratch)? {
Reference::Borrowed(b) => visitor.visit_borrowed_str(b),
Reference::Copied(c) => visitor.visit_str(c),
},
};
value
}
#[inline]
fn deserialize_newtype_struct<V>(self, _: &str, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
#[inline]
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
if self.flat {
return Err(Error::NotSupportedAsValue);
}
visitor.visit_seq(SeqAccess::new(self))
}
#[inline]
fn deserialize_tuple<V>(self, _: usize, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
if self.flat {
return Err(Error::NotSupportedAsValue);
}
visitor.visit_seq(SeqAccess::new(self))
}
#[inline]
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_bool(self.parser.parse_bool()?)
}
#[inline]
fn deserialize_tuple_struct<V>(
self,
_: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_tuple(len, visitor)
}
#[inline]
fn deserialize_enum<V>(
self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_enum(self)
}
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.parser.peek()? {
Some(b'&') | Some(b';') | None => visitor.visit_none(),
_ => visitor.visit_some(self),
}
}
#[inline]
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.parser.parse_ignore()?;
visitor.visit_unit()
}
#[inline]
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let peek = match self.parser.peek()? {
Some(b) => b,
None => return visitor.visit_unit(),
};
match peek {
b'=' => Err(Error::InvalidMapKey),
_ => match self.parser.parse_bytes(&mut self.scratch)? {
Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b),
Reference::Copied(c) => visitor.visit_bytes(c),
},
}
}
#[inline]
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
forward_to_deserialize_any! {
<W: Visitor<'de>>
char str string unit unit_struct map struct
identifier
}
deserialize_number!(deserialize_i8);
deserialize_number!(deserialize_i16);
deserialize_number!(deserialize_i32);
deserialize_number!(deserialize_i64);
deserialize_number!(deserialize_u8);
deserialize_number!(deserialize_u16);
deserialize_number!(deserialize_u32);
deserialize_number!(deserialize_u64);
deserialize_number!(deserialize_f32);
deserialize_number!(deserialize_f64);
}
impl<'de, 'a> de::EnumAccess<'de> for &mut Value<'de, 'a> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: de::DeserializeSeed<'de>,
{
seed.deserialize(
self.parser
.parse_str(&mut self.scratch)?
.into_deserializer(),
)
.map(|res| (res, self))
}
}
impl<'de, 'a> de::VariantAccess<'de> for &mut Value<'de, 'a> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
Err(Error::NotSupportedAsValue)
}
fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
Err(Error::NotSupportedAsValue)
}
fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
where
T: de::DeserializeSeed<'de>,
{
Err(Error::NotSupportedAsValue)
}
}
pub(crate) struct SeqAccess<'de, 'a, 'b> {
value: &'b mut Value<'de, 'a>,
end: bool,
}
impl<'de, 'a, 'b> SeqAccess<'de, 'a, 'b> {
pub(crate) fn new(value: &'b mut Value<'de, 'a>) -> Self {
Self { value, end: false }
}
}
impl<'de, 'a, 'b> de::SeqAccess<'de> for SeqAccess<'de, 'a, 'b> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: de::DeserializeSeed<'de>,
{
if self.end {
return Ok(None);
}
let res = match self.value.parser.parse_one_seq_value()? {
Some(slice) => seed
.deserialize(&mut Value::new_flat(&mut Parser::new(slice)))
.map(Some),
None => Ok(None),
};
match self.value.parser.peek()? {
None | Some(b'&') | Some(b';') => {
self.value.parser.discard();
self.end = true
}
Some(b',') => self.value.parser.discard(),
_ => {}
};
res
}
}