use std::collections::BTreeMap;
use serde::{
de::{
value::{MapDeserializer, SeqDeserializer},
DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, Unexpected, VariantAccess,
Visitor,
},
Deserialize, Deserializer,
};
use crate::{Error, Value};
impl<'de> Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str(
"a JSON-like value (number, float, string, object, boolean, array, or null)",
)
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = BTreeMap::new();
while let Some((key, value)) = access.next_entry()? {
map.insert(key, value);
}
Ok(Value::Object(map))
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Null)
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v.into())
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v.into())
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v.into())
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v.into())
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v.into())
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut elements = Vec::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(element) = seq.next_element()? {
elements.push(element);
}
Ok(Value::Array(elements))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Null)
}
}
deserializer.deserialize_any(ValueVisitor)
}
}
struct EnumDeserializer {
variant: String,
value: Option<Value>,
}
impl<'de> EnumAccess<'de> for EnumDeserializer {
type Error = Error;
type Variant = VariantDeserializer;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error>
where
V: DeserializeSeed<'de>,
{
let variant = self.variant.into_deserializer();
let visitor = VariantDeserializer { value: self.value };
seed.deserialize(variant).map(|v| (v, visitor))
}
}
struct VariantDeserializer {
value: Option<Value>,
}
impl<'de> VariantAccess<'de> for VariantDeserializer {
type Error = Error;
fn unit_variant(self) -> Result<(), Error> {
match self.value {
Some(value) => Deserialize::deserialize(value),
None => Ok(()),
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
where
T: DeserializeSeed<'de>,
{
match self.value {
Some(value) => seed.deserialize(value),
None => Err(serde::de::Error::invalid_type(
Unexpected::UnitVariant,
&"newtype variant",
)),
}
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.value {
Some(Value::Array(v)) => {
if v.is_empty() {
visitor.visit_unit()
} else {
visit_array(v, visitor)
}
}
Some(other) => Err(serde::de::Error::invalid_type(
other.unexpected(),
&"tuple variant",
)),
None => Err(serde::de::Error::invalid_type(
Unexpected::UnitVariant,
&"tuple variant",
)),
}
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.value {
Some(Value::Object(v)) => visit_object(v, visitor),
Some(other) => Err(serde::de::Error::invalid_type(
other.unexpected(),
&"struct variant",
)),
None => Err(serde::de::Error::invalid_type(
Unexpected::UnitVariant,
&"struct variant",
)),
}
}
}
impl<'de> IntoDeserializer<'de, Error> for Value {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
impl<'de> Deserializer<'de> for Value {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Self::Null => visitor.visit_unit(),
Self::Bool(b) => visitor.visit_bool(b),
Self::String(str) => visitor.visit_str(str.as_str()),
Self::Unsigned(i) => visitor.visit_u64(i),
Self::Signed(i) => visitor.visit_i64(i),
Self::Float(f) => visitor.visit_f64(f),
Self::Array(arr) => visit_array(arr, visitor),
Self::Object(obj) => visit_object(obj, visitor),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(bool) = self.as_bool() {
return visitor.visit_bool(bool);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(i) = self.as_signed() {
return visitor.visit_i64(i);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(i) = self.as_unsigned() {
return visitor.visit_u64(i);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_f64(visitor)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(f) = self.as_float() {
return visitor.visit_f64(f);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(s) = self.as_str() {
return visitor.visit_str(s);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(s) = self.as_str() {
return visitor.visit_string(s.to_owned());
}
Err(self.invalid_type(&visitor))
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Value::String(v) => visitor.visit_str(v.as_str()),
Value::Array(v) => visit_array(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Value::Null => visitor.visit_none(),
_ => visitor.visit_some(self),
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if self.is_null() {
return visitor.visit_unit();
}
Err(self.invalid_type(&visitor))
}
fn deserialize_unit_struct<V>(
self,
_: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(
self,
_: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Self::Array(arr) = self {
return visit_array(arr, visitor);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_tuple<V>(self, _: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_: &'static str,
_: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Self::Object(obj) = self {
return visit_object(obj, visitor);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_struct<V>(
self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Value::Object(obj) => visit_object(obj, visitor),
Value::Array(arr) => visit_array(arr, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_enum<V>(
self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let (variant, value) = match self {
Value::Object(value) => {
let mut iter = value.into_iter();
let (variant, value) = match iter.next() {
Some(v) => v,
None => {
return Err(serde::de::Error::invalid_value(
Unexpected::Map,
&"map with a single key",
));
}
};
if iter.next().is_some() {
return Err(serde::de::Error::invalid_value(
Unexpected::Map,
&"map with a single key",
));
}
(variant, Some(value))
}
Value::String(variant) => (variant, None),
other => {
return Err(serde::de::Error::invalid_type(
other.unexpected(),
&"string or map",
));
}
};
visitor.visit_enum(EnumDeserializer { variant, value })
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_unit()
}
}
impl<'de> IntoDeserializer<'de, Error> for &'de Value {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
impl<'de> Deserializer<'de> for &'de Value {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Value::Null => visitor.visit_unit(),
Value::Bool(b) => visitor.visit_bool(*b),
Value::String(str) => visitor.visit_borrowed_str(str),
Value::Unsigned(i) => visitor.visit_u64(*i),
Value::Signed(i) => visitor.visit_i64(*i),
Value::Float(f) => visitor.visit_f64(*f),
Value::Array(arr) => visit_array_ref(arr, visitor),
Value::Object(obj) => visit_object_ref(obj, visitor),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(bool) = self.as_bool() {
return visitor.visit_bool(bool);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(i) = self.as_signed() {
return visitor.visit_i64(i);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(i) = self.as_unsigned() {
return visitor.visit_u64(i);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_f64(visitor)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(f) = self.as_float() {
return visitor.visit_f64(f);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(s) = self.as_str() {
return visitor.visit_borrowed_str(s);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Some(s) = self.as_str() {
return visitor.visit_borrowed_str(s);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Value::String(v) => visitor.visit_borrowed_str(v),
Value::Array(v) => visit_array_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Value::Null => visitor.visit_none(),
_ => visitor.visit_some(self),
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if self.is_null() {
return visitor.visit_unit();
}
Err(self.invalid_type(&visitor))
}
fn deserialize_unit_struct<V>(
self,
_: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(
self,
_: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Value::Array(arr) = self {
return visit_array_ref(arr, visitor);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_tuple<V>(self, _: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_: &'static str,
_: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Value::Object(obj) = self {
return visit_object_ref(obj, visitor);
}
Err(self.invalid_type(&visitor))
}
fn deserialize_struct<V>(
self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
Value::Object(obj) => visit_object_ref(obj, visitor),
Value::Array(arr) => visit_array_ref(arr, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_enum<V>(
self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let (variant, value) = match self {
Value::Object(value) => {
let mut iter = value.iter();
let (variant, value) = match iter.next() {
Some(v) => v,
None => {
return Err(serde::de::Error::invalid_value(
Unexpected::Map,
&"map with a single key",
));
}
};
if iter.next().is_some() {
return Err(serde::de::Error::invalid_value(
Unexpected::Map,
&"map with a single key",
));
}
(variant, Some(value))
}
Value::String(variant) => (variant, None),
other => {
return Err(serde::de::Error::invalid_type(
other.unexpected(),
&"string or map",
));
}
};
visitor.visit_enum(EnumRefDeserializer { variant, value })
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_unit()
}
}
struct EnumRefDeserializer<'de> {
variant: &'de str,
value: Option<&'de Value>,
}
impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> {
type Error = Error;
type Variant = VariantRefDeserializer<'de>;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
where
V: DeserializeSeed<'de>,
{
let variant = self.variant.into_deserializer();
let visitor = VariantRefDeserializer { value: self.value };
seed.deserialize(variant).map(|v| (v, visitor))
}
}
struct VariantRefDeserializer<'de> {
value: Option<&'de Value>,
}
impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> {
type Error = Error;
fn unit_variant(self) -> Result<(), Error> {
match self.value {
Some(value) => Deserialize::deserialize(value),
None => Ok(()),
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
where
T: DeserializeSeed<'de>,
{
match self.value {
Some(value) => seed.deserialize(value),
None => Err(serde::de::Error::invalid_type(
Unexpected::UnitVariant,
&"newtype variant",
)),
}
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.value {
Some(Value::Array(v)) => {
if v.is_empty() {
visitor.visit_unit()
} else {
visit_array_ref(v, visitor)
}
}
Some(other) => Err(serde::de::Error::invalid_type(
other.unexpected(),
&"tuple variant",
)),
None => Err(serde::de::Error::invalid_type(
Unexpected::UnitVariant,
&"tuple variant",
)),
}
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.value {
Some(Value::Object(v)) => visit_object_ref(v, visitor),
Some(other) => Err(serde::de::Error::invalid_type(
other.unexpected(),
&"struct variant",
)),
None => Err(serde::de::Error::invalid_type(
Unexpected::UnitVariant,
&"struct variant",
)),
}
}
}
fn visit_object<'de, V>(object: BTreeMap<String, Value>, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
visitor.visit_map(&mut MapDeserializer::new(object.into_iter()))
}
fn visit_object_ref<'de, V>(
object: &'de BTreeMap<String, Value>,
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
visitor.visit_map(&mut MapDeserializer::new(
object.iter().map(|(key, value)| (key.as_str(), value)),
))
}
fn visit_array<'de, V>(array: Vec<Value>, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
visitor.visit_seq(&mut SeqDeserializer::new(array.into_iter()))
}
fn visit_array_ref<'de, V>(array: &'de [Value], visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
visitor.visit_seq(&mut SeqDeserializer::new(array.iter()))
}
#[test]
fn deserialize_from_owned() {
use crate::test::{test_struct, test_value, TestStruct};
let value = test_value();
let my_struct_result = TestStruct::deserialize(value);
assert!(my_struct_result.is_ok());
assert!(my_struct_result.unwrap() == test_struct());
}
#[test]
fn deserialize_from_ref() {
use crate::test::{test_struct, test_value, TestStruct};
let value = test_value();
let my_struct_result = TestStruct::deserialize(&value);
assert!(my_struct_result.is_ok());
assert!(my_struct_result.unwrap() == test_struct());
}