Simplify codegen logic in deserializing seq

This commit is contained in:
David Tolnay
2017-01-12 21:41:27 -08:00
parent 4b66463011
commit 2df529cac5
+13 -16
View File
@@ -302,15 +302,15 @@ fn deserialize_seq(
fields: &[Field], fields: &[Field],
is_struct: bool, is_struct: bool,
) -> Tokens { ) -> Tokens {
let vars = (0..fields.len()).map(field_i as fn(_) -> _);
let mut index_in_seq = 0usize; let mut index_in_seq = 0usize;
let let_values = fields.iter() let let_values = vars.clone().zip(fields)
.enumerate() .map(|(var, field)| {
.map(|(i, field)| {
let name = Ident::new(format!("__field{}", i));
if field.attrs.skip_deserializing() { if field.attrs.skip_deserializing() {
let default = expr_is_missing(&field.attrs); let default = expr_is_missing(&field.attrs);
quote! { quote! {
let #name = #default; let #var = #default;
} }
} else { } else {
let visit = match field.attrs.deserialize_with() { let visit = match field.attrs.deserialize_with() {
@@ -329,7 +329,7 @@ fn deserialize_seq(
} }
}; };
let assign = quote! { let assign = quote! {
let #name = match #visit { let #var = match #visit {
Some(value) => { value }, Some(value) => { value },
None => { None => {
try!(visitor.end()); try!(visitor.end());
@@ -343,20 +343,13 @@ fn deserialize_seq(
}); });
let result = if is_struct { let result = if is_struct {
let args = fields.iter() let names = fields.iter().map(|f| &f.ident);
.enumerate()
.map(|(i, field)| {
let ident = field.ident.clone().expect("struct contains unnamed fields");
let value = Ident::new(format!("__field{}", i));
quote!(#ident: #value)
});
quote! { quote! {
#type_path { #(#args),* } #type_path { #( #names: #vars ),* }
} }
} else { } else {
let args = (0..fields.len()).map(|i| Ident::new(format!("__field{}", i)));
quote! { quote! {
#type_path ( #(#args),* ) #type_path ( #(#vars),* )
} }
}; };
@@ -871,6 +864,10 @@ fn deserialize_map(
} }
} }
fn field_i(i: usize) -> Ident {
Ident::new(format!("__field{}", i))
}
/// This function wraps the expression in `#[serde(deserialize_with="...")]` in /// This function wraps the expression in `#[serde(deserialize_with="...")]` in
/// a trait to prevent it from accessing the internal `Deserialize` state. /// a trait to prevent it from accessing the internal `Deserialize` state.
fn wrap_deserialize_with( fn wrap_deserialize_with(