diff --git a/json/src/de.rs b/json/src/de.rs index 8120b30..cdcccf8 100644 --- a/json/src/de.rs +++ b/json/src/de.rs @@ -743,10 +743,31 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter> } } - fn missing_field(&mut self, _field: &'static str) -> Result + fn missing_field(&mut self, field: &'static str) -> Result where V: de::Deserialize, { - let mut de = de::value::ValueDeserializer::into_deserializer(()); + use std; + + struct MissingFieldDeserializer(&'static str); + + impl de::Deserializer for MissingFieldDeserializer { + type Error = de::value::Error; + + fn visit(&mut self, _visitor: V) -> std::result::Result + where V: de::Visitor, + { + let &mut MissingFieldDeserializer(field) = self; + Err(de::value::Error::MissingFieldError(field)) + } + + fn visit_option(&mut self, mut visitor: V) -> std::result::Result + where V: de::Visitor, + { + visitor.visit_none() + } + } + + let mut de = MissingFieldDeserializer(field); Ok(try!(de::Deserialize::deserialize(&mut de))) } } diff --git a/json_tests/tests/test_json.rs b/json_tests/tests/test_json.rs index 6c2e003..ce8cda8 100644 --- a/json_tests/tests/test_json.rs +++ b/json_tests/tests/test_json.rs @@ -919,6 +919,8 @@ fn test_parse_struct() { ("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), ("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 7)), ("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 14)), + ("{}", Error::SyntaxError(ErrorCode::MissingField("inner"), 1, 2)), + (r#"{"inner": [{"b": 42, "c": []}]}"#, Error::SyntaxError(ErrorCode::MissingField("a"), 1, 29)), ]); test_parse_ok(vec![ @@ -944,15 +946,6 @@ fn test_parse_struct() { ), ]); - let v: Outer = from_str("{}").unwrap(); - - assert_eq!( - v, - Outer { - inner: vec![], - } - ); - let v: Outer = from_str( "[ [ @@ -1065,7 +1058,7 @@ fn test_multiline_errors() { } #[test] -fn test_missing_field() { +fn test_missing_option_field() { #[derive(Debug, PartialEq, Deserialize)] struct Foo { x: Option, @@ -1086,6 +1079,18 @@ fn test_missing_field() { assert_eq!(value, Foo { x: Some(5) }); } +#[test] +fn test_missing_nonoption_field() { + #[derive(Debug, PartialEq, Deserialize)] + struct Foo { + x: u32, + } + + test_parse_err::(vec![ + ("{}", Error::SyntaxError(ErrorCode::MissingField("x"), 1, 2)), + ]); +} + #[test] fn test_missing_renamed_field() { #[derive(Debug, PartialEq, Deserialize)]