Merge pull request #134 from erickt/err

Add Error::length_mismatch, Error::type_mismatch, and de::Type
This commit is contained in:
Erick Tryzelaar
2015-08-10 10:07:51 -07:00
4 changed files with 92 additions and 40 deletions
+21 -20
View File
@@ -34,6 +34,7 @@ use de::{
Error, Error,
MapVisitor, MapVisitor,
SeqVisitor, SeqVisitor,
Type,
VariantVisitor, VariantVisitor,
Visitor, Visitor,
}; };
@@ -85,7 +86,7 @@ impl Visitor for BoolVisitor {
match s.trim() { match s.trim() {
"true" => Ok(true), "true" => Ok(true),
"false" => Ok(false), "false" => Ok(false),
_ => Err(Error::syntax("expected `true` or `false`")), _ => Err(Error::type_mismatch(Type::Bool)),
} }
} }
} }
@@ -101,14 +102,14 @@ impl Deserialize for bool {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num_method { macro_rules! impl_deserialize_num_method {
($src_ty:ty, $method:ident, $from_method:ident) => { ($src_ty:ty, $method:ident, $from_method:ident, $ty:expr) => {
#[inline] #[inline]
fn $method<E>(&mut self, v: $src_ty) -> Result<T, E> fn $method<E>(&mut self, v: $src_ty) -> Result<T, E>
where E: Error, where E: Error,
{ {
match FromPrimitive::$from_method(v) { match FromPrimitive::$from_method(v) {
Some(v) => Ok(v), Some(v) => Ok(v),
None => Err(Error::syntax("expected a number")), None => Err(Error::type_mismatch($ty)),
} }
} }
} }
@@ -132,24 +133,24 @@ impl<
> Visitor for PrimitiveVisitor<T> { > Visitor for PrimitiveVisitor<T> {
type Value = T; type Value = T;
impl_deserialize_num_method!(isize, visit_isize, from_isize); impl_deserialize_num_method!(isize, visit_isize, from_isize, Type::Isize);
impl_deserialize_num_method!(i8, visit_i8, from_i8); impl_deserialize_num_method!(i8, visit_i8, from_i8, Type::I8);
impl_deserialize_num_method!(i16, visit_i16, from_i16); impl_deserialize_num_method!(i16, visit_i16, from_i16, Type::I16);
impl_deserialize_num_method!(i32, visit_i32, from_i32); impl_deserialize_num_method!(i32, visit_i32, from_i32, Type::I32);
impl_deserialize_num_method!(i64, visit_i64, from_i64); impl_deserialize_num_method!(i64, visit_i64, from_i64, Type::I64);
impl_deserialize_num_method!(usize, visit_usize, from_usize); impl_deserialize_num_method!(usize, visit_usize, from_usize, Type::Usize);
impl_deserialize_num_method!(u8, visit_u8, from_u8); impl_deserialize_num_method!(u8, visit_u8, from_u8, Type::U8);
impl_deserialize_num_method!(u16, visit_u16, from_u16); impl_deserialize_num_method!(u16, visit_u16, from_u16, Type::U16);
impl_deserialize_num_method!(u32, visit_u32, from_u32); impl_deserialize_num_method!(u32, visit_u32, from_u32, Type::U32);
impl_deserialize_num_method!(u64, visit_u64, from_u64); impl_deserialize_num_method!(u64, visit_u64, from_u64, Type::U64);
impl_deserialize_num_method!(f32, visit_f32, from_f32); impl_deserialize_num_method!(f32, visit_f32, from_f32, Type::F32);
impl_deserialize_num_method!(f64, visit_f64, from_f64); impl_deserialize_num_method!(f64, visit_f64, from_f64, Type::F64);
#[inline] #[inline]
fn visit_str<E>(&mut self, v: &str) -> Result<T, E> fn visit_str<E>(&mut self, v: &str) -> Result<T, E>
where E: Error, where E: Error,
{ {
str::FromStr::from_str(v.trim()).or(Err(Error::syntax("expected a str"))) str::FromStr::from_str(v.trim()).or(Err(Error::type_mismatch(Type::Str)))
} }
} }
@@ -200,7 +201,7 @@ impl Visitor for CharVisitor {
let mut iter = v.chars(); let mut iter = v.chars();
if let Some(v) = iter.next() { if let Some(v) = iter.next() {
if iter.next().is_some() { if iter.next().is_some() {
Err(Error::syntax("expected a character")) Err(Error::type_mismatch(Type::Char))
} else { } else {
Ok(v) Ok(v)
} }
@@ -243,7 +244,7 @@ impl Visitor for StringVisitor {
{ {
match str::from_utf8(v) { match str::from_utf8(v) {
Ok(s) => Ok(s.to_string()), Ok(s) => Ok(s.to_string()),
Err(_) => Err(Error::syntax("expected utf8 `&[u8]`")), Err(_) => Err(Error::type_mismatch(Type::String)),
} }
} }
@@ -252,7 +253,7 @@ impl Visitor for StringVisitor {
{ {
match String::from_utf8(v) { match String::from_utf8(v) {
Ok(s) => Ok(s), Ok(s) => Ok(s),
Err(_) => Err(Error::syntax("expected utf8 `&[u8]`")), Err(_) => Err(Error::type_mismatch(Type::String)),
} }
} }
} }
@@ -900,7 +901,7 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
_ => { _ => {
match str::from_utf8(value) { match str::from_utf8(value) {
Ok(value) => Err(Error::unknown_field(value)), Ok(value) => Err(Error::unknown_field(value)),
Err(_) => Err(Error::syntax("expected a `&[u8]`")), Err(_) => Err(Error::type_mismatch(Type::String)),
} }
} }
} }
+67 -16
View File
@@ -5,16 +5,67 @@ pub mod value;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
pub trait Error { /// `Error` is a trait that allows a `Deserialize` to generically create a
/// `Deserializer` error.
pub trait Error: Sized {
/// Raised when there is general error when deserializing a type.
fn syntax(msg: &str) -> Self; fn syntax(msg: &str) -> Self;
/// Raised when a fixed sized sequence or map was passed in the wrong amount of arguments.
fn length_mismatch(_len: usize) -> Self {
Error::syntax("incorrect length")
}
/// Raised when a `Deserialize` was passed an incorrect type.
fn type_mismatch(_type: Type) -> Self {
Error::syntax("incorrect type")
}
/// Raised when a `Deserialize` type unexpectedly hit the end of the stream.
fn end_of_stream() -> Self; fn end_of_stream() -> Self;
/// Raised when a `Deserialize` struct type received an unexpected struct field.
fn unknown_field(field: &str) -> Self; fn unknown_field(field: &str) -> Self;
/// Raised when a `Deserialize` struct type did not receive a field.
fn missing_field(field: &'static str) -> Self; fn missing_field(field: &'static str) -> Self;
} }
/// `Type` represents all the primitive types that can be deserialized. This is used by
/// `Error::kind_mismatch`.
pub enum Type {
Bool,
Usize,
U8,
U16,
U32,
U64,
Isize,
I8,
I16,
I32,
I64,
F32,
F64,
Char,
Str,
String,
Unit,
Option,
Seq,
Map,
UnitStruct,
NewtypeStruct,
TupleStruct,
Struct,
Tuple,
Enum,
StructVariant,
TupleVariant,
UnitVariant,
Bytes,
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
pub trait Deserialize { pub trait Deserialize {
@@ -304,7 +355,7 @@ pub trait Visitor {
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E> fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected a bool")) Err(Error::type_mismatch(Type::Bool))
} }
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E> fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
@@ -334,7 +385,7 @@ pub trait Visitor {
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E> fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected a i64")) Err(Error::type_mismatch(Type::I64))
} }
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E> fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
@@ -364,7 +415,7 @@ pub trait Visitor {
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E> fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected a u64")) Err(Error::type_mismatch(Type::U64))
} }
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E> fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
@@ -376,7 +427,7 @@ pub trait Visitor {
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E> fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected a f64")) Err(Error::type_mismatch(Type::F64))
} }
#[inline] #[inline]
@@ -391,7 +442,7 @@ pub trait Visitor {
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E> fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected a str")) Err(Error::type_mismatch(Type::Str))
} }
#[inline] #[inline]
@@ -404,7 +455,7 @@ pub trait Visitor {
fn visit_unit<E>(&mut self) -> Result<Self::Value, E> fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected a unit")) Err(Error::type_mismatch(Type::Unit))
} }
#[inline] #[inline]
@@ -417,37 +468,37 @@ pub trait Visitor {
fn visit_none<E>(&mut self) -> Result<Self::Value, E> fn visit_none<E>(&mut self) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected an Option::None")) Err(Error::type_mismatch(Type::Option))
} }
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error> fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer, where D: Deserializer,
{ {
Err(Error::syntax("expected an Option::Some")) Err(Error::type_mismatch(Type::Option))
} }
fn visit_newtype_struct<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error> fn visit_newtype_struct<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer, where D: Deserializer,
{ {
Err(Error::syntax("expected a newtype struct")) Err(Error::type_mismatch(Type::NewtypeStruct))
} }
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error> fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor, where V: SeqVisitor,
{ {
Err(Error::syntax("expected a sequence")) Err(Error::type_mismatch(Type::Seq))
} }
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error> fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor, where V: MapVisitor,
{ {
Err(Error::syntax("expected a map")) Err(Error::type_mismatch(Type::Map))
} }
fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E> fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::syntax("expected a &[u8]")) Err(Error::type_mismatch(Type::Bytes))
} }
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E> fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E>
@@ -593,7 +644,7 @@ pub trait VariantVisitor {
/// `visit_unit` is called when deserializing a variant with no values. /// `visit_unit` is called when deserializing a variant with no values.
fn visit_unit(&mut self) -> Result<(), Self::Error> { fn visit_unit(&mut self) -> Result<(), Self::Error> {
Err(Error::syntax("expected a univ variant")) Err(Error::type_mismatch(Type::UnitVariant))
} }
/// `visit_newtype` is called when deserializing a variant with a single value. By default this /// `visit_newtype` is called when deserializing a variant with a single value. By default this
@@ -612,7 +663,7 @@ pub trait VariantVisitor {
_visitor: V) -> Result<V::Value, Self::Error> _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor where V: Visitor
{ {
Err(Error::syntax("expected a tuple variant")) Err(Error::type_mismatch(Type::TupleVariant))
} }
/// `visit_struct` is called when deserializing a struct-like variant. /// `visit_struct` is called when deserializing a struct-like variant.
@@ -621,7 +672,7 @@ pub trait VariantVisitor {
_visitor: V) -> Result<V::Value, Self::Error> _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor where V: Visitor
{ {
Err(Error::syntax("expected a struct variant")) Err(Error::type_mismatch(Type::StructVariant))
} }
} }
+2 -2
View File
@@ -261,7 +261,7 @@ impl<I, T> de::SeqVisitor for SeqDeserializer<I>
if self.len == 0 { if self.len == 0 {
Ok(()) Ok(())
} else { } else {
Err(de::Error::end_of_stream()) Err(de::Error::length_mismatch(self.len))
} }
} }
@@ -382,7 +382,7 @@ impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
if self.len == 0 { if self.len == 0 {
Ok(()) Ok(())
} else { } else {
Err(de::Error::end_of_stream()) Err(de::Error::length_mismatch(self.len))
} }
} }
+2 -2
View File
@@ -843,7 +843,7 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
if self.len == 0 { if self.len == 0 {
Ok(()) Ok(())
} else { } else {
Err(de::Error::end_of_stream()) Err(de::Error::length_mismatch(self.len))
} }
} }
@@ -888,7 +888,7 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
if self.len == 0 { if self.len == 0 {
Ok(()) Ok(())
} else { } else {
Err(de::Error::end_of_stream()) Err(de::Error::length_mismatch(self.len))
} }
} }