Fix an error message test, simlify some serde code

This commit is contained in:
Alex Crichton 2016-03-11 01:32:16 -08:00
parent d02e622330
commit 3345fea319
2 changed files with 110 additions and 106 deletions

View file

@ -57,6 +57,8 @@ pub enum DecodeErrorKind {
CustomError(String), CustomError(String),
/// The end of the TOML input was reached too soon /// The end of the TOML input was reached too soon
EndOfStream, EndOfStream,
/// Produced by serde ...
InvalidType(&'static str),
} }
/// Decodes a TOML value into a decodable type. /// Decodes a TOML value into a decodable type.
@ -197,6 +199,9 @@ impl fmt::Display for DecodeError {
EndOfStream => { EndOfStream => {
write!(f, "end of stream") write!(f, "end of stream")
} }
InvalidType(s) => {
write!(f, "invalid type: {}", s)
}
CustomError(ref s) => { CustomError(ref s) => {
write!(f, "custom error: {}", s) write!(f, "custom error: {}", s)
} }
@ -223,6 +228,7 @@ impl error::Error for DecodeError {
NilTooLong => "nonzero length string representing nil", NilTooLong => "nonzero length string representing nil",
SyntaxError => "syntax error", SyntaxError => "syntax error",
EndOfStream => "end of stream", EndOfStream => "end of stream",
InvalidType(..) => "invalid type",
CustomError(..) => "custom error", CustomError(..) => "custom error",
} }
} }

View file

@ -3,29 +3,6 @@ use Value;
use super::{Decoder, DecodeError, DecodeErrorKind}; use super::{Decoder, DecodeError, DecodeErrorKind};
use std::collections::BTreeMap; use std::collections::BTreeMap;
fn se2toml(err: de::value::Error, ty: &'static str) -> DecodeError {
match err {
de::value::Error::Custom(s) => de::Error::custom(s),
de::value::Error::EndOfStream => de::Error::end_of_stream(),
de::value::Error::MissingField(s) => {
DecodeError {
field: Some(s.to_string()),
kind: DecodeErrorKind::ExpectedField(Some(ty)),
}
},
de::value::Error::UnknownField(s) => {
DecodeError {
field: Some(s.to_string()),
kind: DecodeErrorKind::UnknownField,
}
},
de::value::Error::InvalidType(ty) => de::Error::invalid_type(ty),
de::value::Error::InvalidLength(l) => de::Error::invalid_length(l),
de::value::Error::InvalidValue(v) => de::Error::invalid_value(&v),
de::value::Error::UnknownVariant(v) => de::Error::unknown_variant(&v),
}
}
impl de::Deserializer for Decoder { impl de::Deserializer for Decoder {
type Error = DecodeError; type Error = DecodeError;
@ -34,21 +11,11 @@ impl de::Deserializer for Decoder {
where V: de::Visitor where V: de::Visitor
{ {
match self.toml.take() { match self.toml.take() {
Some(Value::String(s)) => { Some(Value::String(s)) => visitor.visit_string(s),
visitor.visit_string(s).map_err(|e| se2toml(e, "string")) Some(Value::Integer(i)) => visitor.visit_i64(i),
} Some(Value::Float(f)) => visitor.visit_f64(f),
Some(Value::Integer(i)) => { Some(Value::Boolean(b)) => visitor.visit_bool(b),
visitor.visit_i64(i).map_err(|e| se2toml(e, "integer")) Some(Value::Datetime(s)) => visitor.visit_string(s),
}
Some(Value::Float(f)) => {
visitor.visit_f64(f).map_err(|e| se2toml(e, "float"))
}
Some(Value::Boolean(b)) => {
visitor.visit_bool(b).map_err(|e| se2toml(e, "bool"))
}
Some(Value::Datetime(s)) => {
visitor.visit_string(s).map_err(|e| se2toml(e, "date"))
}
Some(Value::Array(a)) => { Some(Value::Array(a)) => {
let len = a.len(); let len = a.len();
let iter = a.into_iter(); let iter = a.into_iter();
@ -62,34 +29,18 @@ impl de::Deserializer for Decoder {
value: None, value: None,
}) })
} }
None => Err(de::Error::end_of_stream()), None => Err(self.err(DecodeErrorKind::EndOfStream)),
} }
} }
fn deserialize_isize<V>(&mut self, visitor: V) fn deserialize_bool<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError> -> Result<V::Value, DecodeError>
where V: de::Visitor where V: de::Visitor
{ {
self.deserialize_i64(visitor) match self.toml.take() {
Some(Value::Boolean(b)) => visitor.visit_bool(b),
ref found => Err(self.mismatch("bool", found)),
} }
fn deserialize_i8<V>(&mut self, visitor: V) -> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i16<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
} }
fn deserialize_i64<V>(&mut self, mut visitor: V) fn deserialize_i64<V>(&mut self, mut visitor: V)
@ -97,50 +48,15 @@ impl de::Deserializer for Decoder {
where V: de::Visitor where V: de::Visitor
{ {
match self.toml.take() { match self.toml.take() {
Some(Value::Integer(f)) => { Some(Value::Integer(f)) => visitor.visit_i64(f),
visitor.visit_i64(f).map_err(|e| se2toml(e, "integer"))
}
ref found => Err(self.mismatch("integer", found)), ref found => Err(self.mismatch("integer", found)),
} }
} }
fn deserialize_usize<V>(&mut self, visitor: V) fn deserialize_u64<V>(&mut self, v: V) -> Result<V::Value, DecodeError>
-> Result<V::Value, DecodeError>
where V: de::Visitor where V: de::Visitor
{ {
self.deserialize_i64(visitor) self.deserialize_i64(v)
}
fn deserialize_u8<V>(&mut self, visitor: V) -> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u16<V>(&mut self, visitor: V) -> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u64<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_f32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_f64(visitor)
} }
fn deserialize_f64<V>(&mut self, mut visitor: V) fn deserialize_f64<V>(&mut self, mut visitor: V)
@ -148,13 +64,33 @@ impl de::Deserializer for Decoder {
where V: de::Visitor where V: de::Visitor
{ {
match self.toml.take() { match self.toml.take() {
Some(Value::Float(f)) => { Some(Value::Float(f)) => visitor.visit_f64(f),
visitor.visit_f64(f).map_err(|e| se2toml(e, "float"))
}
ref found => Err(self.mismatch("float", found)), ref found => Err(self.mismatch("float", found)),
} }
} }
fn deserialize_str<V>(&mut self, mut visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor,
{
match self.toml.take() {
Some(Value::String(s)) => visitor.visit_string(s),
ref found => Err(self.mismatch("string", found)),
}
}
fn deserialize_char<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
match self.toml.take() {
Some(Value::String(ref s)) if s.chars().count() == 1 => {
visitor.visit_char(s.chars().next().unwrap())
}
ref found => return Err(self.mismatch("string", found)),
}
}
fn deserialize_option<V>(&mut self, mut visitor: V) fn deserialize_option<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError> -> Result<V::Value, DecodeError>
where V: de::Visitor where V: de::Visitor
@ -172,13 +108,29 @@ impl de::Deserializer for Decoder {
{ {
if self.toml.is_none() { if self.toml.is_none() {
let iter = None::<i32>.into_iter(); let iter = None::<i32>.into_iter();
let e = visitor.visit_seq(de::value::SeqDeserializer::new(iter, 0)); visitor.visit_seq(de::value::SeqDeserializer::new(iter, 0))
e.map_err(|e| se2toml(e, "array"))
} else { } else {
self.deserialize(visitor) self.deserialize(visitor)
} }
} }
fn deserialize_map<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor,
{
match self.toml.take() {
Some(Value::Table(t)) => {
visitor.visit_map(MapVisitor {
iter: t.into_iter(),
de: self,
key: None,
value: None,
})
}
ref found => Err(self.mismatch("table", found)),
}
}
fn deserialize_enum<V>(&mut self, fn deserialize_enum<V>(&mut self,
_enum: &str, _enum: &str,
variants: &[&str], variants: &[&str],
@ -238,7 +190,7 @@ impl de::VariantVisitor for VariantVisitor {
let mut de = self.variant.into_deserializer(); let mut de = self.variant.into_deserializer();
de::Deserialize::deserialize(&mut de).map_err(|e| se2toml(e, "variant")) de::Deserialize::deserialize(&mut de)
} }
fn visit_unit(&mut self) -> Result<(), DecodeError> { fn visit_unit(&mut self) -> Result<(), DecodeError> {
@ -364,6 +316,45 @@ impl de::Error for DecodeError {
kind: DecodeErrorKind::UnknownField, kind: DecodeErrorKind::UnknownField,
} }
} }
fn invalid_type(ty: de::Type) -> Self {
DecodeError {
field: None,
kind: DecodeErrorKind::InvalidType(match ty {
de::Type::Bool => "bool",
de::Type::Usize |
de::Type::U8 |
de::Type::U16 |
de::Type::U32 |
de::Type::U64 |
de::Type::Isize |
de::Type::I8 |
de::Type::I16 |
de::Type::I32 |
de::Type::I64 => "integer",
de::Type::F32 |
de::Type::F64 => "float",
de::Type::Char |
de::Type::Str |
de::Type::String => "string",
de::Type::Seq => "array",
de::Type::Struct |
de::Type::Map => "table",
de::Type::Unit => "Unit",
de::Type::Option => "Option",
de::Type::UnitStruct => "UnitStruct",
de::Type::NewtypeStruct => "NewtypeStruct",
de::Type::TupleStruct => "TupleStruct",
de::Type::FieldName => "FieldName",
de::Type::Tuple => "Tuple",
de::Type::Enum => "Enum",
de::Type::VariantName => "VariantName",
de::Type::StructVariant => "StructVariant",
de::Type::TupleVariant => "TupleVariant",
de::Type::UnitVariant => "UnitVariant",
de::Type::Bytes => "Bytes",
})
}
}
} }
struct MapVisitor<'a, I> { struct MapVisitor<'a, I> {
@ -444,6 +435,13 @@ impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
} }
fn end(&mut self) -> Result<(), DecodeError> { fn end(&mut self) -> Result<(), DecodeError> {
if let Some(v) = self.value.take() {
self.put_value_back(v);
}
while let Some((k, v)) = self.iter.next() {
self.key = Some(k);
self.put_value_back(v);
}
Ok(()) Ok(())
} }
@ -452,7 +450,7 @@ impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
// See if the type can deserialize from a unit. // See if the type can deserialize from a unit.
match de::Deserialize::deserialize(&mut UnitDeserializer) { match de::Deserialize::deserialize(&mut UnitDeserializer) {
Err(DecodeError { Err(DecodeError {
kind: DecodeErrorKind::SyntaxError, kind: DecodeErrorKind::InvalidType(..),
field, field,
}) => Err(DecodeError { }) => Err(DecodeError {
field: field.or(Some(field_name.to_string())), field: field.or(Some(field_name.to_string())),