use std::borrow::Cow;
use std::collections::HashMap;
use std::fmt;
use serde::de;
use serde::de::Error as DeError;
use key::Key;
use value::Value;
use list::List;
use table::Table;
use error::Error;
struct KeyVisitor;
impl<'de> de::Visitor<'de> for KeyVisitor {
type Value = Key<'de>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("boolean, integer, or string")
}
fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Key::from(value))
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Key::from(value))
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
if value > i64::max_value() as u64 {
Err(E::invalid_value(
de::Unexpected::Unsigned(value),
&"a value within the bounds of i64",
))
} else {
Ok(Key::from(value))
}
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_string(value.to_string())
}
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Key::from(value))
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Key::from(value))
}
}
impl<'de> de::Deserialize<'de> for Key<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_any(KeyVisitor)
}
}
struct ValueVisitor;
impl<'de> de::Visitor<'de> for ValueVisitor {
type Value = Value<'de>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("null, boolean, integer, float, string, list, or table")
}
fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Value::from(value))
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Value::from(value))
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
if value > i64::max_value() as u64 {
Err(E::invalid_value(
de::Unexpected::Unsigned(value),
&"a value within the bounds of i64",
))
} else {
Ok(Value::from(value))
}
}
fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Value::from(value))
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_string(value.to_string())
}
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Value::from(value))
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Value::from(value))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_unit()
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_any(self)
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Value::Null)
}
fn visit_newtype_struct<D>(self, deserializer: D)
-> Result<Self::Value, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_any(self)
}
fn visit_seq<A>(self, access: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
Ok(Value::from(TableVisitor.visit_seq(access)?))
}
fn visit_map<A>(self, access: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>,
{
Ok(Value::from(TableVisitor.visit_map(access)?))
}
}
impl<'de> de::Deserialize<'de> for Value<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_any(ValueVisitor)
}
}
struct ListVisitor;
impl<'de> de::Visitor<'de> for ListVisitor {
type Value = List<'de>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("compound type: seq, tuple")
}
fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut list = List::with_vec(
Vec::with_capacity(access.size_hint().unwrap_or(0)),
);
while let Some(element) = access.next_element::<Value>()? {
list.push(element);
}
Ok(list)
}
}
impl<'de> de::Deserialize<'de> for List<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_seq(ListVisitor)
}
}
struct TableVisitor;
impl<'de> de::Visitor<'de> for TableVisitor {
type Value = Table<'de>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("compound type: map, struct, enum")
}
fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>,
{
let mut table = Table::with_map(
HashMap::with_capacity(access.size_hint().unwrap_or(0))
);
while let Some((key, value)) = access.next_entry::<Key, Value>()? {
table.insert(key, value);
}
Ok(table)
}
}
impl<'de> de::Deserialize<'de> for Table<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_map(TableVisitor)
}
}
impl de::Error for Error {
fn custom<T>(msg: T) -> Error
where
T: fmt::Display,
{
Error {
message: msg.to_string(),
}
}
}
impl<'a, 'b> From<&'b Key<'a>> for de::Unexpected<'b> {
fn from(value: &'b Key<'a>) -> de::Unexpected<'b> {
match value {
Key::Bool(x) => de::Unexpected::Bool(*x),
Key::I64(x) => de::Unexpected::Signed(*x),
Key::Bytes(x) => de::Unexpected::Bytes(x),
Key::String(x) => de::Unexpected::Str(x),
}
}
}
impl<'a, 'b> From<&'b Value<'a>> for de::Unexpected<'b> {
fn from(value: &'b Value<'a>) -> de::Unexpected<'b> {
match value {
Value::Null => de::Unexpected::Unit,
Value::Bool(x) => de::Unexpected::Bool(*x),
Value::I64(x) => de::Unexpected::Signed(*x),
Value::F64(x) => de::Unexpected::Float(*x),
Value::Bytes(x) => de::Unexpected::Bytes(x),
Value::String(x) => de::Unexpected::Str(x),
Value::List(_) => de::Unexpected::Seq,
Value::Table(_) => de::Unexpected::Map,
}
}
}
impl<'de> de::Deserializer<'de> for Key<'de> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
match self {
Key::Bool(value) => visitor.visit_bool(value),
Key::I64(value) => visitor.visit_i64(value),
Key::Bytes(cow) => match *cow {
Cow::Borrowed(value) => visitor.visit_borrowed_bytes(value),
Cow::Owned(value) => visitor.visit_byte_buf(value),
},
Key::String(cow) => match *cow {
Cow::Borrowed(value) => visitor.visit_borrowed_str(value),
Cow::Owned(value) => visitor.visit_string(value),
},
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
map struct enum identifier ignored_any
}
}
impl<'de: 'a, 'a> de::Deserializer<'de> for &'de Key<'a> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
match self {
Key::Bool(value) => visitor.visit_bool(*value),
Key::I64(value) => visitor.visit_i64(*value),
Key::Bytes(value) => visitor.visit_borrowed_bytes(value),
Key::String(value) => visitor.visit_borrowed_str(value),
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
map struct enum identifier ignored_any
}
}
impl<'de> de::Deserializer<'de> for Value<'de> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
match self {
Value::Null => visitor.visit_unit(),
Value::Bool(value) => visitor.visit_bool(value),
Value::I64(value) => visitor.visit_i64(value),
Value::F64(value) => visitor.visit_f64(value),
Value::Bytes(cow) => match *cow {
Cow::Borrowed(value) => visitor.visit_borrowed_bytes(value),
Cow::Owned(value) => visitor.visit_byte_buf(value),
},
Value::String(cow) => match *cow {
Cow::Borrowed(value) => visitor.visit_borrowed_str(value),
Cow::Owned(value) => visitor.visit_string(value),
},
Value::List(cow) => match *cow {
Cow::Borrowed(value) => {
visitor.visit_seq(IterAccess::new(value.iter()))
},
Cow::Owned(value) => {
visitor.visit_seq(IterAccess::new(value.into_iter()))
},
},
Value::Table(cow) => match *cow {
Cow::Borrowed(value) => {
visitor.visit_map(IterAccess::new(value.iter()))
},
Cow::Owned(value) => {
visitor.visit_map(IterAccess::new(value.into_iter()))
},
},
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit unit_struct seq tuple map struct tuple_struct identifier
ignored_any
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::Null = self {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V)
-> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::Table(cow) = self {
match *cow {
Cow::Borrowed(value) => {
visitor.visit_enum(IterAccess::new(value.iter()))
},
Cow::Owned(value) => {
visitor.visit_enum(IterAccess::new(value.into_iter()))
},
}
} else {
self.deserialize_any(visitor)
}
}
}
impl<'de> de::VariantAccess<'de> for Value<'de> {
type Error = Error;
fn unit_variant(self) -> Result<(), Self::Error> {
if let Value::Null = self {
Ok(())
} else {
Err(Error::invalid_type((&self).into(), &"unit variant"))
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
seed.deserialize(self)
}
fn tuple_variant<V>(self, _len: usize, visitor: V)
-> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::List(cow) = self {
match *cow {
Cow::Borrowed(value) => {
visitor.visit_seq(IterAccess::new(value.iter()))
},
Cow::Owned(value) => {
visitor.visit_seq(IterAccess::new(value.into_iter()))
},
}
} else {
Err(Error::invalid_type((&self).into(), &"tuple variant"))
}
}
fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V)
-> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::Table(cow) = self {
match *cow {
Cow::Borrowed(value) => {
visitor.visit_map(IterAccess::new(value.iter()))
},
Cow::Owned(value) => {
visitor.visit_map(IterAccess::new(value.into_iter()))
},
}
} else {
Err(Error::invalid_type((&self).into(), &"struct variant"))
}
}
}
impl<'de: 'a, 'a> de::Deserializer<'de> for &'de Value<'a> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
match self {
Value::Null => visitor.visit_unit(),
Value::Bool(value) => visitor.visit_bool(*value),
Value::I64(value) => visitor.visit_i64(*value),
Value::F64(value) => visitor.visit_f64(*value),
Value::Bytes(value) => visitor.visit_borrowed_bytes(value),
Value::String(value) => visitor.visit_borrowed_str(value),
Value::List(value) => {
visitor.visit_seq(IterAccess::new(value.iter()))
},
Value::Table(value) => {
visitor.visit_map(IterAccess::new(value.iter()))
},
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit unit_struct seq map tuple tuple_struct struct identifier
ignored_any
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::Null = self {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V)
-> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::Table(value) = self {
visitor.visit_enum(IterAccess::new(value.iter()))
} else {
self.deserialize_any(visitor)
}
}
}
impl<'de: 'a, 'a> de::VariantAccess<'de> for &'de Value<'a> {
type Error = Error;
fn unit_variant(self) -> Result<(), Self::Error> {
if let Value::Null = self {
Ok(())
} else {
Err(Error::invalid_type(self.into(), &"unit variant"))
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
seed.deserialize(self)
}
fn tuple_variant<V>(self, _len: usize, visitor: V)
-> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::Table(value) = self {
visitor.visit_seq(IterAccess::new(
(0..)
.map(|i| value.get::<_, Value>(i))
.take_while(|option| option.is_some())
.map(|option| option.unwrap())
))
} else {
Err(Error::invalid_type(self.into(), &"tuple variant"))
}
}
fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V)
-> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
if let Value::Table(value) = self {
visitor.visit_map(IterAccess::new(value.iter()))
} else {
Err(Error::invalid_type(self.into(), &"struct variant"))
}
}
}
pub struct IterAccess<I, V>
where
I: Iterator,
{
iter: I,
cached: Option<V>,
}
impl<I, V> IterAccess<I, V>
where
I: Iterator,
{
pub fn new<J>(iter: J) -> IterAccess<I, V>
where
J: IntoIterator<IntoIter=I, Item=I::Item>,
{
IterAccess {
iter: iter.into_iter(),
cached: None,
}
}
}
impl<'de, I, V> de::SeqAccess<'de> for IterAccess<I, V>
where
I: Iterator<Item=V>,
V: de::Deserializer<'de>,
{
type Error = V::Error;
fn next_element_seed<S>(&mut self, seed: S)
-> Result<Option<S::Value>, Self::Error>
where
S: de::DeserializeSeed<'de>,
{
if let Some(element) = self.iter.next() {
Ok(Some(seed.deserialize(element)?))
} else {
Ok(None)
}
}
}
impl<'de, I, K, V> de::MapAccess<'de> for IterAccess<I, V>
where
I: Iterator<Item=(K, V)>,
K: de::Deserializer<'de>,
V: de::Deserializer<'de, Error=K::Error>,
{
type Error = K::Error;
fn next_key_seed<S>(&mut self, seed: S)
-> Result<Option<S::Value>, Self::Error>
where
S: de::DeserializeSeed<'de>,
{
if let Some((key, value)) = self.iter.next() {
self.cached = Some(value);
Ok(Some(seed.deserialize(key)?))
} else {
Ok(None)
}
}
fn next_value_seed<S>(&mut self, seed: S)
-> Result<S::Value, Self::Error>
where
S: de::DeserializeSeed<'de>,
{
seed.deserialize(self.cached.take().unwrap())
}
fn next_entry_seed<S, T>(&mut self, kseed: S, vseed: T)
-> Result<Option<(S::Value, T::Value)>, Self::Error>
where
S: de::DeserializeSeed<'de>,
T: de::DeserializeSeed<'de>,
{
if let Some((key, value)) = self.iter.next() {
Ok(Some((kseed.deserialize(key)?, vseed.deserialize(value)?)))
} else {
Ok(None)
}
}
}
impl<'de, I, K, V> de::EnumAccess<'de> for IterAccess<I, V>
where
I: Iterator<Item=(K, V)>,
K: de::Deserializer<'de>,
V: de::VariantAccess<'de, Error=K::Error>,
{
type Variant = V;
type Error = V::Error;
fn variant_seed<S>(mut self, seed: S)
-> Result<(S::Value, Self::Variant), Self::Error>
where
S: de::DeserializeSeed<'de>
{
if let Some((variant, value)) = self.iter.next() {
Ok((seed.deserialize(variant)?, value))
} else {
Err(Self::Error::custom("Deserialized table does not contain a tag."))
}
}
}