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

View File

@ -32,10 +32,19 @@ pub trait Error: Sized + error::Error {
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 {
Error::syntax(&format!("Unknown field `{}`", field))
}
/// Raised when a `Deserialize` struct type did not receive a field.
fn missing_field(field: &'static str) -> Self;
/// Raised when a `Deserialize` enum type received an unexpected variant.
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

View File

@ -566,6 +566,7 @@ fn deserialize_item_enum(
.collect()
),
container_attrs,
true,
);
let variants_expr = builder.expr().ref_().slice()
@ -807,6 +808,7 @@ fn deserialize_field_visitor(
builder: &aster::AstBuilder,
field_names: Vec<P<ast::Expr>>,
container_attrs: &attr::ContainerAttrs,
is_variant: bool,
) -> Vec<P<ast::Item>> {
// Create the field names for the fields.
let field_idents: Vec<ast::Ident> = (0 .. field_names.len())
@ -838,10 +840,16 @@ fn deserialize_field_visitor(
})
.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,
match value {
$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();
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))
} 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,
@ -947,7 +955,8 @@ fn deserialize_struct_visitor(
cx,
builder,
try!(field_exprs),
container_attrs
container_attrs,
false,
);
let visit_map_expr = try!(deserialize_map(

View File

@ -8,7 +8,13 @@ use num::rational::Ratio;
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()),
)
}

View File

@ -371,6 +371,7 @@ pub enum Error {
SyntaxError,
EndOfStreamError,
UnknownFieldError(String),
UnknownVariantError(String),
MissingFieldError(&'static str),
InvalidName(&'static str),
InvalidValue(String),
@ -395,6 +396,10 @@ impl de::Error for Error {
Error::UnknownFieldError(field.to_owned())
}
fn unknown_variant(variant: &str) -> Error {
Error::UnknownVariantError(variant.to_owned())
}
fn missing_field(field: &'static str) -> Error {
Error::MissingFieldError(field)
}