feat(de): Add an Error::unknown_variant error.

Closes #169
This commit is contained in:
Erick Tryzelaar
2016-02-21 16:26:52 -08:00
parent 4d10eef55d
commit 740865b637
4 changed files with 47 additions and 8 deletions
+12 -3
View File
@@ -32,10 +32,19 @@ pub trait Error: Sized + error::Error {
fn end_of_stream() -> Self; fn end_of_stream() -> Self;
/// Raised when a `Deserialize` struct type received an unexpected struct field. /// Raised when a `Deserialize` struct type received an unexpected struct field.
fn unknown_field(field: &str) -> Self; fn unknown_field(field: &str) -> Self {
Error::syntax(&format!("Unknown field `{}`", field))
}
/// Raised when a `Deserialize` struct type did not receive a field. /// Raised when a `Deserialize` enum type received an unexpected variant.
fn missing_field(field: &'static str) -> Self; fn unknown_variant(field: &str) -> Self {
Error::syntax(&format!("Unknown variant `{}`", field))
}
/// raised when a `deserialize` struct type did not receive a field.
fn missing_field(field: &'static str) -> Self {
Error::syntax(&format!("Missing field `{}`", field))
}
} }
/// `Type` represents all the primitive types that can be deserialized. This is used by /// `Type` represents all the primitive types that can be deserialized. This is used by
+13 -4
View File
@@ -566,6 +566,7 @@ fn deserialize_item_enum(
.collect() .collect()
), ),
container_attrs, container_attrs,
true,
); );
let variants_expr = builder.expr().ref_().slice() let variants_expr = builder.expr().ref_().slice()
@@ -807,6 +808,7 @@ fn deserialize_field_visitor(
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
field_names: Vec<P<ast::Expr>>, field_names: Vec<P<ast::Expr>>,
container_attrs: &attr::ContainerAttrs, container_attrs: &attr::ContainerAttrs,
is_variant: bool,
) -> Vec<P<ast::Item>> { ) -> Vec<P<ast::Item>> {
// Create the field names for the fields. // Create the field names for the fields.
let field_idents: Vec<ast::Ident> = (0 .. field_names.len()) let field_idents: Vec<ast::Ident> = (0 .. field_names.len())
@@ -838,10 +840,16 @@ fn deserialize_field_visitor(
}) })
.collect(); .collect();
let (index_error_msg, unknown_ident) = if is_variant {
(builder.expr().str("expected a variant"), builder.id("unknown_variant"))
} else {
(builder.expr().str("expected a field"), builder.id("unknown_field"))
};
let index_body = quote_expr!(cx, let index_body = quote_expr!(cx,
match value { match value {
$index_field_arms $index_field_arms
_ => { Err(::serde::de::Error::syntax("expected a field")) } _ => { Err(::serde::de::Error::syntax($index_error_msg)) }
} }
); );
@@ -853,10 +861,10 @@ fn deserialize_field_visitor(
}) })
.collect(); .collect();
let fallthrough_arm_expr = if !container_attrs.deny_unknown_fields() { let fallthrough_arm_expr = if !is_variant && !container_attrs.deny_unknown_fields() {
quote_expr!(cx, Ok(__Field::__ignore)) quote_expr!(cx, Ok(__Field::__ignore))
} else { } else {
quote_expr!(cx, Err(::serde::de::Error::unknown_field(value))) quote_expr!(cx, Err(::serde::de::Error::$unknown_ident(value)))
}; };
let str_body = quote_expr!(cx, let str_body = quote_expr!(cx,
@@ -947,7 +955,8 @@ fn deserialize_struct_visitor(
cx, cx,
builder, builder,
try!(field_exprs), try!(field_exprs),
container_attrs container_attrs,
false,
); );
let visit_map_expr = try!(deserialize_map( let visit_map_expr = try!(deserialize_map(
+17 -1
View File
@@ -8,7 +8,13 @@ use num::rational::Ratio;
use serde::de::{Deserializer, Visitor}; use serde::de::{Deserializer, Visitor};
use token::{Token, assert_de_tokens, assert_de_tokens_ignore}; use token::{
Error,
Token,
assert_de_tokens,
assert_de_tokens_ignore,
assert_de_tokens_error,
};
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -600,3 +606,13 @@ declare_tests! {
], ],
} }
} }
#[test]
fn test_enum_error() {
assert_de_tokens_error::<Enum>(
vec![
Token::EnumUnit("Enum", "Foo"),
],
Error::UnknownVariantError("Foo".to_owned()),
)
}
+5
View File
@@ -371,6 +371,7 @@ pub enum Error {
SyntaxError, SyntaxError,
EndOfStreamError, EndOfStreamError,
UnknownFieldError(String), UnknownFieldError(String),
UnknownVariantError(String),
MissingFieldError(&'static str), MissingFieldError(&'static str),
InvalidName(&'static str), InvalidName(&'static str),
InvalidValue(String), InvalidValue(String),
@@ -395,6 +396,10 @@ impl de::Error for Error {
Error::UnknownFieldError(field.to_owned()) Error::UnknownFieldError(field.to_owned())
} }
fn unknown_variant(variant: &str) -> Error {
Error::UnknownVariantError(variant.to_owned())
}
fn missing_field(field: &'static str) -> Error { fn missing_field(field: &'static str) -> Error {
Error::MissingFieldError(field) Error::MissingFieldError(field)
} }