From 438157e662d2092dd49513a9791aa75788180c35 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 17 Nov 2018 09:37:02 +1300 Subject: Only validate table keys against fields when deserializing enum. Issue #225 --- src/de.rs | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/de.rs b/src/de.rs index 869f7ae..9d5a417 100644 --- a/src/de.rs +++ b/src/de.rs @@ -501,14 +501,21 @@ impl<'de> de::Deserializer<'de> for StrDeserializer<'de> { struct ValueDeserializer<'a> { value: Value<'a>, + validate_struct_keys: bool, } impl<'a> ValueDeserializer<'a> { fn new(value: Value<'a>) -> ValueDeserializer<'a> { ValueDeserializer { value: value, + validate_struct_keys: false, } } + + fn with_struct_key_validation(mut self) -> Self { + self.validate_struct_keys = true; + self + } } impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> { @@ -557,26 +564,28 @@ impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> { } } - match &self.value.e { - &E::InlineTable(ref values) | &E::DottedTable(ref values) => { - let extra_fields = values.iter() - .filter_map(|(ref key, ref _val)| { - if !fields.contains(&&(**key)) { - Some(key.clone()) - } else { - None - } - }) - .collect::>>(); + if self.validate_struct_keys { + match &self.value.e { + &E::InlineTable(ref values) | &E::DottedTable(ref values) => { + let extra_fields = values.iter() + .filter_map(|(ref key, ref _val)| { + if !fields.contains(&&(**key)) { + Some(key.clone()) + } else { + None + } + }) + .collect::>>(); - if !extra_fields.is_empty() { - return Err(Error::from_kind(ErrorKind::UnexpectedKeys { - keys: extra_fields.iter().map(|k| k.to_string()).collect::>(), - available: fields, - })); + if !extra_fields.is_empty() { + return Err(Error::from_kind(ErrorKind::UnexpectedKeys { + keys: extra_fields.iter().map(|k| k.to_string()).collect::>(), + available: fields, + })); + } } + _ => {} } - _ => {} } if name == spanned::NAME && fields == &[spanned::START, spanned::END, spanned::VALUE] { @@ -900,7 +909,7 @@ impl<'de> de::VariantAccess<'de> for TableEnumDeserializer<'de> { V: de::Visitor<'de>, { de::Deserializer::deserialize_struct( - ValueDeserializer::new(self.value), + ValueDeserializer::new(self.value).with_struct_key_validation(), "", // TODO: this should be the variant name fields, visitor, -- cgit v1.2.3