Address comment and make test pass

This commit is contained in:
Vincent Prouillet 2017-04-28 13:00:37 +09:00
parent c675b4f259
commit a6f22570ae
3 changed files with 28 additions and 90 deletions

View file

@ -122,8 +122,7 @@ enum ErrorKind {
/// type. /// type.
Custom, Custom,
/// TODO /// A struct was expected but something else was found
ExpectedEnum,
ExpectedString, ExpectedString,
#[doc(hidden)] #[doc(hidden)]
@ -206,16 +205,15 @@ impl<'de, 'b> de::Deserializer<'de> for &'b mut Deserializer<'de> {
) -> Result<V::Value, Error> ) -> Result<V::Value, Error>
where V: de::Visitor<'de> where V: de::Visitor<'de>
{ {
if self.peek_char()? == '"' { if let Some(next) = self.next()? {
// Visit a unit variant. match next {
match self.next()?.unwrap() { Token::String { val, .. } => {
Token::String { ref val, .. } => { visitor.visit_enum(val.into_deserializer())
visitor.visit_enum(val.clone().into_deserializer())
}, },
_ => Err(Error::from_kind(ErrorKind::ExpectedString)) _ => Err(Error::from_kind(ErrorKind::ExpectedString))
} }
} else { } else {
Err(Error::from_kind(ErrorKind::ExpectedEnum)) Err(Error::from_kind(ErrorKind::UnexpectedEof))
} }
} }
@ -517,10 +515,24 @@ impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> {
visitor.visit_some(self) visitor.visit_some(self)
} }
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V
) -> Result<V::Value, Error>
where V: de::Visitor<'de>
{
match self.value {
Value::String(val) => visitor.visit_enum(val.into_deserializer()),
_ => Err(Error::from_kind(ErrorKind::ExpectedString))
}
}
forward_to_deserialize_any! { forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map unit newtype_struct identifier bytes byte_buf map unit newtype_struct identifier
ignored_any unit_struct tuple_struct tuple enum ignored_any unit_struct tuple_struct tuple
} }
} }
@ -988,10 +1000,6 @@ impl<'a> Deserializer<'a> {
self.tokens.peek().map_err(|e| self.token_error(e)) self.tokens.peek().map_err(|e| self.token_error(e))
} }
fn peek_char(&mut self) -> Result<char, Error> {
self.input.chars().next().ok_or(Error::from_kind(ErrorKind::UnexpectedEof))
}
fn eof(&self) -> Error { fn eof(&self) -> Error {
self.error(self.input.len(), ErrorKind::UnexpectedEof) self.error(self.input.len(), ErrorKind::UnexpectedEof)
} }
@ -1125,7 +1133,6 @@ impl fmt::Display for Error {
ErrorKind::RedefineAsArray => "table redefined as array".fmt(f)?, ErrorKind::RedefineAsArray => "table redefined as array".fmt(f)?,
ErrorKind::EmptyTableKey => "empty table key found".fmt(f)?, ErrorKind::EmptyTableKey => "empty table key found".fmt(f)?,
ErrorKind::Custom => self.inner.message.fmt(f)?, ErrorKind::Custom => self.inner.message.fmt(f)?,
ErrorKind::ExpectedEnum => "expected enum".fmt(f)?,
ErrorKind::ExpectedString => "expected string".fmt(f)?, ErrorKind::ExpectedString => "expected string".fmt(f)?,
ErrorKind::__Nonexhaustive => panic!(), ErrorKind::__Nonexhaustive => panic!(),
} }
@ -1169,7 +1176,6 @@ impl error::Error for Error {
ErrorKind::RedefineAsArray => "table redefined as array", ErrorKind::RedefineAsArray => "table redefined as array",
ErrorKind::EmptyTableKey => "empty table key found", ErrorKind::EmptyTableKey => "empty table key found",
ErrorKind::Custom => "a custom error", ErrorKind::Custom => "a custom error",
ErrorKind::ExpectedEnum => "expected enum",
ErrorKind::ExpectedString => "expected string", ErrorKind::ExpectedString => "expected string",
ErrorKind::__Nonexhaustive => panic!(), ErrorKind::__Nonexhaustive => panic!(),
} }

View file

@ -421,9 +421,9 @@ impl<'a, 'b> ser::Serializer for &'b mut Serializer<'a> {
fn serialize_unit_variant(self, fn serialize_unit_variant(self,
_name: &'static str, _name: &'static str,
_variant_index: u32, _variant_index: u32,
_variant: &'static str) variant: &'static str)
-> Result<(), Self::Error> { -> Result<(), Self::Error> {
self.serialize_str(_variant) self.serialize_str(variant)
} }
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T)

View file

@ -516,20 +516,11 @@ impl<'de> de::Deserializer<'de> for Value {
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
let (variant, value) = match self { match self {
Value::String(variant) => (variant, None), Value::String(variant) => visitor.visit_enum(variant.into_deserializer()),
_ => { _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"string only")),
return Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"string only"),); }
} }
};
visitor.visit_enum(
EnumDeserializer {
variant: variant,
value: value,
},
)
}
// `None` is interpreted as a missing field so be sure to implement `Some` // `None` is interpreted as a missing field so be sure to implement `Some`
// as a present field. // as a present field.
@ -545,65 +536,6 @@ impl<'de> de::Deserializer<'de> for Value {
tuple ignored_any newtype_struct identifier tuple ignored_any newtype_struct identifier
} }
} }
struct EnumDeserializer {
variant: String,
value: Option<Value>,
}
impl<'de> de::EnumAccess<'de> for EnumDeserializer {
type Error = ::de::Error;
type Variant = VariantDeserializer;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Self::Error>
where
V: de::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> de::VariantAccess<'de> for VariantDeserializer {
type Error = ::de::Error;
fn unit_variant(self) -> Result<(), Self::Error> {
match self.value {
Some(value) => de::Deserialize::deserialize(value),
None => Ok(()),
}
}
fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant"))
}
fn tuple_variant<V>(self, _len: usize, _: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"))
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
_: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"))
}
}
struct SeqDeserializer { struct SeqDeserializer {
iter: vec::IntoIter<Value>, iter: vec::IntoIter<Value>,