Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/binary_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@ where
pub(crate) fn convert_to_set(value: crate::AttributeValue) -> crate::Result<crate::AttributeValue> {
let vals = match value {
crate::AttributeValue::L(vals) => vals,
_ => return Err(crate::error::ErrorImpl::NotSetlike.into()),
_ => {
return Err(crate::error::Error::new(
crate::error::ErrorImpl::NotSetlike,
String::new(),
Some(value),
))
}
};

let set = vals
Expand All @@ -132,7 +138,11 @@ pub(crate) fn convert_to_set(value: crate::AttributeValue) -> crate::Result<crat
if let crate::AttributeValue::B(s) = v {
Ok(s)
} else {
Err(crate::error::ErrorImpl::BinarySetExpectedType.into())
Err(crate::error::Error::new(
crate::error::ErrorImpl::BinarySetExpectedType,
String::new(),
Some(v),
))
}
})
.collect::<Result<_, _>>()?;
Expand Down
67 changes: 36 additions & 31 deletions src/de/deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,45 @@ use super::{
deserializer_seq::{
DeserializerSeq, DeserializerSeqBytes, DeserializerSeqNumbers, DeserializerSeqStrings,
},
AttributeValue, Error, ErrorImpl, Result,
AttributeValue, Error, ErrorImpl, ErrorPath, Result,
};
use serde_core::de::{self, IntoDeserializer, Visitor};

/// A structure that deserializes [`AttributeValue`]s into Rust values.
#[derive(Debug)]
pub struct Deserializer {
pub struct Deserializer<'a> {
input: AttributeValue,
path: ErrorPath<'a>,
}

impl Deserializer {
impl<'a> Deserializer<'a> {
/// Create a Deserializer from an AttributeValue
pub fn from_attribute_value(input: AttributeValue) -> Self {
Deserializer { input }
Self::from_attribute_value_path(input, ErrorPath::Root)
}

pub(crate) fn from_attribute_value_path(input: AttributeValue, path: ErrorPath<'a>) -> Self {
Deserializer { input, path }
}

/// Helper that creates an error with context
fn error(self, kind: ErrorImpl) -> Error {
Error::from_path(kind, &self.path, self.input)
}
}

macro_rules! deserialize_number {
($self:expr, $visitor:expr, $ty:ty, $fn:ident) => {
if let AttributeValue::N(n) = $self.input {
let de = DeserializerNumber::from_string(n);
let de = DeserializerNumber::from_string(n, $self.path);
de.$fn($visitor)
} else {
return Err(ErrorImpl::ExpectedNum.into());
return Err($self.error(ErrorImpl::ExpectedNum));
}
};
}

impl<'de> de::Deserializer<'de> for Deserializer {
impl<'de, 'a> de::Deserializer<'de> for Deserializer<'a> {
type Error = Error;

// Look at the input data to decide what Serde data model type to
Expand All @@ -45,7 +55,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
V: Visitor<'de>,
{
if let AttributeValue::N(s) = self.input {
DeserializerNumber::from_string(s).deserialize_any(visitor)
DeserializerNumber::from_string(s, self.path).deserialize_any(visitor)
} else {
match self.input {
AttributeValue::S(_) => self.deserialize_string(visitor),
Expand Down Expand Up @@ -139,7 +149,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
if let AttributeValue::S(s) = self.input {
visitor.visit_string(s)
} else {
Err(ErrorImpl::ExpectedString.into())
Err(self.error(ErrorImpl::ExpectedString))
}
}

Expand All @@ -150,7 +160,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
if let AttributeValue::S(s) = self.input {
visitor.visit_string(s)
} else {
Err(ErrorImpl::ExpectedString.into())
Err(self.error(ErrorImpl::ExpectedString))
}
}

Expand All @@ -160,22 +170,22 @@ impl<'de> de::Deserializer<'de> for Deserializer {
{
match self.input {
AttributeValue::L(l) => {
let deserializer_seq = DeserializerSeq::from_vec(l);
let deserializer_seq = DeserializerSeq::from_vec(l, self.path);
visitor.visit_seq(deserializer_seq)
}
AttributeValue::Ss(ss) => {
let deserializer_seq = DeserializerSeqStrings::from_vec(ss);
visitor.visit_seq(deserializer_seq)
}
AttributeValue::Ns(ns) => {
let deserializer_seq = DeserializerSeqNumbers::from_vec(ns);
let deserializer_seq = DeserializerSeqNumbers::from_vec(ns, self.path);
visitor.visit_seq(deserializer_seq)
}
AttributeValue::Bs(bs) => {
let deserializer_seq = DeserializerSeqBytes::from_vec(bs);
visitor.visit_seq(deserializer_seq)
}
_ => Err(ErrorImpl::ExpectedSeq.into()),
_ => Err(self.error(ErrorImpl::ExpectedSeq)),
}
}

Expand All @@ -184,10 +194,10 @@ impl<'de> de::Deserializer<'de> for Deserializer {
V: Visitor<'de>,
{
if let AttributeValue::M(mut m) = self.input {
let deserializer_map = DeserializerMap::from_item(&mut m);
let deserializer_map = DeserializerMap::from_item(&mut m, self.path);
visitor.visit_map(deserializer_map)
} else {
Err(ErrorImpl::ExpectedMap.into())
Err(self.error(ErrorImpl::ExpectedMap))
}
}

Expand All @@ -198,29 +208,24 @@ impl<'de> de::Deserializer<'de> for Deserializer {
if let AttributeValue::Bool(b) = self.input {
visitor.visit_bool(b)
} else {
Err(ErrorImpl::ExpectedBool.into())
Err(self.error(ErrorImpl::ExpectedBool))
}
}

fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let AttributeValue::S(s) = self.input {
if let AttributeValue::S(s) = &self.input {
let mut chars = s.chars();
if let Some(ch) = chars.next() {
let result = visitor.visit_char(ch)?;
if chars.next().is_some() {
Err(ErrorImpl::ExpectedChar.into())
} else {
Ok(result)
if chars.next().is_none() {
return Ok(result);
}
} else {
Err(ErrorImpl::ExpectedChar.into())
}
} else {
Err(ErrorImpl::ExpectedChar.into())
}
Err(self.error(ErrorImpl::ExpectedChar))
}

fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
Expand All @@ -230,7 +235,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
if let AttributeValue::Null(true) = self.input {
visitor.visit_unit()
} else {
Err(ErrorImpl::ExpectedUnit.into())
Err(self.error(ErrorImpl::ExpectedUnit))
}
}

Expand All @@ -245,8 +250,8 @@ impl<'de> de::Deserializer<'de> for Deserializer {
{
match self.input {
AttributeValue::S(s) => visitor.visit_enum(s.into_deserializer()),
AttributeValue::M(m) => visitor.visit_enum(DeserializerEnum::from_item(m)),
_ => Err(ErrorImpl::ExpectedEnum.into()),
AttributeValue::M(m) => visitor.visit_enum(DeserializerEnum::from_item(m, &self.path)),
_ => Err(self.error(ErrorImpl::ExpectedEnum)),
}
}

Expand All @@ -258,7 +263,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
let de = DeserializerBytes::from_bytes(b);
de.deserialize_bytes(visitor)
} else {
Err(ErrorImpl::ExpectedBytes.into())
Err(self.error(ErrorImpl::ExpectedBytes))
}
}

Expand Down Expand Up @@ -310,7 +315,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
if let AttributeValue::S(s) = self.input {
visitor.visit_string(s)
} else {
Err(ErrorImpl::ExpectedString.into())
Err(self.error(ErrorImpl::ExpectedString))
}
}

Expand All @@ -325,7 +330,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
if let AttributeValue::Null(true) = self.input {
visitor.visit_unit()
} else {
Err(ErrorImpl::ExpectedUnitStruct.into())
Err(self.error(ErrorImpl::ExpectedUnitStruct))
}
}

Expand Down
53 changes: 30 additions & 23 deletions src/de/deserializer_enum.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,58 @@
use super::{AttributeValue, Deserializer, Error, ErrorImpl, Result};
use super::{AttributeValue, Deserializer, Error, ErrorImpl, ErrorPath, Result};
use serde_core::de::{
DeserializeSeed, Deserializer as _, EnumAccess, IntoDeserializer, VariantAccess, Visitor,
};
use std::collections::HashMap;

pub struct DeserializerEnum {
pub struct DeserializerEnum<'a> {
input: HashMap<String, AttributeValue>,
path: &'a ErrorPath<'a>,
}

impl DeserializerEnum {
pub fn from_item(input: HashMap<String, AttributeValue>) -> Self {
Self { input }
impl<'a> DeserializerEnum<'a> {
pub fn from_item(input: HashMap<String, AttributeValue>, path: &'a ErrorPath<'a>) -> Self {
Self { input, path }
}
}

impl<'de> EnumAccess<'de> for DeserializerEnum {
type Variant = DeserializerVariant;
impl<'de, 'a> EnumAccess<'de> for DeserializerEnum<'a> {
type Variant = DeserializerVariant<'a>;
type Error = Error;

fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where
V: DeserializeSeed<'de>,
{
let mut drain = self.input.drain();
let (key, value) = drain
.next()
.ok_or_else(|| ErrorImpl::ExpectedSingleKey.into())?;
if drain.next().is_some() {
return Err(ErrorImpl::ExpectedSingleKey.into());
if self.input.len() != 1 {
return Err(Error::from_path(
ErrorImpl::ExpectedSingleKey,
&self.path,
AttributeValue::M(self.input),
));
}
let deserializer = DeserializerVariant::from_attribute_value(value);
let (key, value) = self.input.into_iter().next().unwrap();
let deserializer = DeserializerVariant::from_attribute_value(
value,
ErrorPath::Enum(key.clone(), self.path),
);
let value = seed.deserialize(key.into_deserializer())?;

Ok((value, deserializer))
}
}

pub struct DeserializerVariant {
pub struct DeserializerVariant<'a> {
input: AttributeValue,
path: ErrorPath<'a>,
}

impl DeserializerVariant {
pub fn from_attribute_value(input: AttributeValue) -> Self {
Self { input }
impl<'a> DeserializerVariant<'a> {
pub fn from_attribute_value(input: AttributeValue, path: ErrorPath<'a>) -> Self {
Self { input, path }
}
}

impl<'de> VariantAccess<'de> for DeserializerVariant {
impl<'de, 'a> VariantAccess<'de> for DeserializerVariant<'a> {
type Error = Error;

fn unit_variant(self) -> Result<()> {
Expand All @@ -56,23 +63,23 @@ impl<'de> VariantAccess<'de> for DeserializerVariant {
where
S: DeserializeSeed<'de>,
{
let deserializer = Deserializer::from_attribute_value(self.input);
let deserializer = Deserializer::from_attribute_value_path(self.input, self.path);
seed.deserialize(deserializer)
}

fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let deserializer = Deserializer::from_attribute_value(self.input);
let deserializer = Deserializer::from_attribute_value_path(self.input, self.path);
deserializer.deserialize_seq(visitor)
}

fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let deserializer = Deserializer::from_attribute_value(self.input);
let deserializer = Deserializer::from_attribute_value_path(self.input, self.path);
deserializer.deserialize_map(visitor)
}
}
Loading