From 516cc8b04ef2e051f1573c04c21e1b4997f11c40 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 8 Jan 2017 00:59:18 -0800 Subject: [PATCH 1/3] Stop generating visit_usize and visit_bytes for FieldVisitor --- serde_codegen/src/de.rs | 94 +++++----------------------------------- testing/tests/test_de.rs | 14 ------ 2 files changed, 11 insertions(+), 97 deletions(-) diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index 163874bd..1a4925fd 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -1,5 +1,5 @@ use syn::{self, aster}; -use quote::{self, Tokens}; +use quote::Tokens; use bound; use internals::ast::{Body, Field, Item, Style, Variant}; @@ -652,38 +652,6 @@ fn deserialize_field_visitor( Some(quote!(__ignore,)) }; - let index_field_arms: Vec<_> = field_idents.iter() - .enumerate() - .map(|(field_index, field_ident)| { - quote! { - #field_index => { Ok(__Field::#field_ident) } - } - }) - .collect(); - - let (index_error_msg, unknown_ident) = if is_variant { - ("expected a variant", aster::id("unknown_variant")) - } else { - ("expected a field", aster::id("unknown_field")) - }; - - let fallthrough_index_arm_expr = if !is_variant && !item_attrs.deny_unknown_fields() { - quote! { - Ok(__Field::__ignore) - } - } else { - quote! { - Err(_serde::de::Error::invalid_value(#index_error_msg)) - } - }; - - let index_body = quote! { - match value { - #(#index_field_arms)* - _ => #fallthrough_index_arm_expr - } - }; - // Match arms to extract a field from a string let str_field_arms: Vec<_> = field_idents.iter().zip(field_names.iter()) .map(|(field_ident, field_name)| { @@ -693,49 +661,18 @@ fn deserialize_field_visitor( }) .collect(); - let fallthrough_str_arm_expr = if !is_variant && !item_attrs.deny_unknown_fields() { + let fallthrough_str_arm_expr = if is_variant { quote! { - Ok(__Field::__ignore) + Err(_serde::de::Error::unknown_variant(value)) + } + } else if item_attrs.deny_unknown_fields() { + quote! { + Err(_serde::de::Error::unknown_field(value)) } } else { - quote! { - Err(_serde::de::Error::#unknown_ident(value)) - } - }; - - let str_body = quote! { - match value { - #(#str_field_arms)* - _ => #fallthrough_str_arm_expr - } - }; - - // Match arms to extract a field from a string - let bytes_field_arms: Vec<_> = field_idents.iter().zip(field_names.iter()) - .map(|(field_ident, field_name)| { - let bytes_field_name = quote::ByteStr(field_name); - quote! { - #bytes_field_name => { Ok(__Field::#field_ident) } - } - }) - .collect(); - - let fallthrough_bytes_arm_expr = if !is_variant && !item_attrs.deny_unknown_fields() { quote! { Ok(__Field::__ignore) } - } else { - quote!({ - let value = ::std::string::String::from_utf8_lossy(value); - Err(_serde::de::Error::#unknown_ident(&value)) - }) - }; - - let bytes_body = quote! { - match value { - #(#bytes_field_arms)* - _ => #fallthrough_bytes_arm_expr - } }; quote! { @@ -755,22 +692,13 @@ fn deserialize_field_visitor( impl _serde::de::Visitor for __FieldVisitor { type Value = __Field; - fn visit_usize<__E>(&mut self, value: usize) -> ::std::result::Result<__Field, __E> - where __E: _serde::de::Error - { - #index_body - } - fn visit_str<__E>(&mut self, value: &str) -> ::std::result::Result<__Field, __E> where __E: _serde::de::Error { - #str_body - } - - fn visit_bytes<__E>(&mut self, value: &[u8]) -> ::std::result::Result<__Field, __E> - where __E: _serde::de::Error - { - #bytes_body + match value { + #(#str_field_arms)* + _ => #fallthrough_str_arm_expr + } } } diff --git a/testing/tests/test_de.rs b/testing/tests/test_de.rs index 280d427f..43d50620 100644 --- a/testing/tests/test_de.rs +++ b/testing/tests/test_de.rs @@ -723,20 +723,6 @@ declare_tests! { Token::EnumMapEnd, ], } - test_enum_unit_usize { - Enum::Unit => &[ - Token::EnumStart("Enum"), - Token::Usize(0), - Token::Unit, - ], - } - test_enum_unit_bytes { - Enum::Unit => &[ - Token::EnumStart("Enum"), - Token::Bytes(b"Unit"), - Token::Unit, - ], - } test_box { Box::new(0i32) => &[Token::I32(0)], } From 1f8b8036078ee6a99c6e2ded6e36bf4a85bd32fb Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 9 Jan 2017 00:37:37 -0800 Subject: [PATCH 2/3] Repetition for field visitor arms --- serde_codegen/src/de.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index 1a4925fd..e75a7c96 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -642,7 +642,7 @@ fn deserialize_field_visitor( is_variant: bool, ) -> Tokens { // Create the field names for the fields. - let field_idents: Vec<_> = (0 .. field_names.len()) + let ref field_idents: Vec<_> = (0 .. field_names.len()) .map(|i| aster::id(format!("__field{}", i))) .collect(); @@ -652,16 +652,7 @@ fn deserialize_field_visitor( Some(quote!(__ignore,)) }; - // Match arms to extract a field from a string - let str_field_arms: Vec<_> = field_idents.iter().zip(field_names.iter()) - .map(|(field_ident, field_name)| { - quote! { - #field_name => { Ok(__Field::#field_ident) } - } - }) - .collect(); - - let fallthrough_str_arm_expr = if is_variant { + let fallthrough_arm = if is_variant { quote! { Err(_serde::de::Error::unknown_variant(value)) } @@ -696,8 +687,10 @@ fn deserialize_field_visitor( where __E: _serde::de::Error { match value { - #(#str_field_arms)* - _ => #fallthrough_str_arm_expr + #( + #field_names => Ok(__Field::#field_idents), + )* + _ => #fallthrough_arm } } } From 90d4d7b37b21d64f69425b1851f10d7d65bf3db4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 9 Jan 2017 00:43:13 -0800 Subject: [PATCH 3/3] Restore the old FieldVisitor tests as error tests --- testing/tests/test_de.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/testing/tests/test_de.rs b/testing/tests/test_de.rs index 43d50620..d1879fe8 100644 --- a/testing/tests/test_de.rs +++ b/testing/tests/test_de.rs @@ -3,7 +3,7 @@ use std::net; use std::path::PathBuf; use std::time::Duration; -use serde::Deserialize; +use serde::de::{Deserialize, Type}; extern crate fnv; use self::fnv::FnvHasher; @@ -833,4 +833,20 @@ declare_error_tests! { ], Error::DuplicateField("a"), } + test_enum_unit_usize { + &[ + Token::EnumStart("Enum"), + Token::Usize(0), + Token::Unit, + ], + Error::InvalidType(Type::U64), + } + test_enum_unit_bytes { + &[ + Token::EnumStart("Enum"), + Token::Bytes(b"Unit"), + Token::Unit, + ], + Error::InvalidType(Type::Bytes), + } }