Do not emit an in-place deserialization path for struct as map

This commit is contained in:
Armin Ronacher 2018-03-18 18:27:35 +01:00
parent 61b167be9a
commit d44f12907b

View File

@ -268,7 +268,11 @@ fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<St
let code = match cont.data { let code = match cont.data {
Data::Struct(Style::Struct, ref fields) => { Data::Struct(Style::Struct, ref fields) => {
deserialize_struct_in_place(None, params, fields, &cont.attrs, None) if let Some(code) = deserialize_struct_in_place(None, params, fields, &cont.attrs, None) {
code
} else {
return None;
}
} }
Data::Struct(Style::Tuple, ref fields) | Data::Struct(Style::Newtype, ref fields) => { Data::Struct(Style::Tuple, ref fields) | Data::Struct(Style::Newtype, ref fields) => {
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None) deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
@ -890,13 +894,19 @@ fn deserialize_struct_in_place(
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
deserializer: Option<Tokens>, deserializer: Option<Tokens>,
) -> Fragment { ) -> Option<Fragment> {
let is_enum = variant_ident.is_some(); let is_enum = variant_ident.is_some();
let as_map = deserializer.is_none() && !is_enum && match cattrs.repr() { let as_map = deserializer.is_none() && !is_enum && match cattrs.repr() {
attr::ContainerRepr::Struct | attr::ContainerRepr::Auto => false, attr::ContainerRepr::Struct | attr::ContainerRepr::Auto => false,
attr::ContainerRepr::Map => true, attr::ContainerRepr::Map => true,
}; };
// for now we do not support in_place deserialization for structs that
// are represented as map.
if as_map {
return None;
}
let this = &params.this; let this = &params.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
split_with_de_lifetime(params); split_with_de_lifetime(params);
@ -909,11 +919,8 @@ fn deserialize_struct_in_place(
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs)); let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs));
let (field_visitor, fields_stmt, visit_map) = if as_map { let (field_visitor, fields_stmt, visit_map) = deserialize_struct_as_struct_in_place_visitor(
deserialize_struct_as_map_in_place_visitor(params, fields, cattrs) params, fields, cattrs);
} else {
deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs)
};
let field_visitor = Stmts(field_visitor); let field_visitor = Stmts(field_visitor);
let fields_stmt = fields_stmt.map(Stmts); let fields_stmt = fields_stmt.map(Stmts);
@ -933,10 +940,6 @@ fn deserialize_struct_in_place(
quote! { quote! {
_serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
} }
} else if as_map {
quote! {
_serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
}
} else { } else {
let type_name = cattrs.name().deserialize_name(); let type_name = cattrs.name().deserialize_name();
quote! { quote! {
@ -951,24 +954,20 @@ fn deserialize_struct_in_place(
quote!(mut __seq) quote!(mut __seq)
}; };
let visit_seq = if as_map { let visit_seq = quote! {
None #[inline]
} else { fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
Some(quote! { where __A: _serde::de::SeqAccess<#delife>
#[inline] {
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> #visit_seq
where __A: _serde::de::SeqAccess<#delife> }
{
#visit_seq
}
})
}; };
let in_place_impl_generics = de_impl_generics.in_place(); let in_place_impl_generics = de_impl_generics.in_place();
let in_place_ty_generics = de_ty_generics.in_place(); let in_place_ty_generics = de_ty_generics.in_place();
let place_life = place_lifetime(); let place_life = place_lifetime();
quote_block! { Some(quote_block! {
#field_visitor #field_visitor
struct __Visitor #in_place_impl_generics #where_clause { struct __Visitor #in_place_impl_generics #where_clause {
@ -996,7 +995,7 @@ fn deserialize_struct_in_place(
#fields_stmt #fields_stmt
#dispatch #dispatch
} })
} }
fn deserialize_enum( fn deserialize_enum(
@ -2233,26 +2232,6 @@ fn deserialize_struct_as_struct_in_place_visitor(
(field_visitor, Some(fields_stmt), visit_map) (field_visitor, Some(fields_stmt), visit_map)
} }
#[cfg(feature = "deserialize_in_place")]
fn deserialize_struct_as_map_in_place_visitor(
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
) -> (Fragment, Option<Fragment>, Fragment) {
let field_names_idents: Vec<_> = fields
.iter()
.enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
.collect();
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, true);
let visit_map = deserialize_map_in_place(params, fields, cattrs);
(field_visitor, None, visit_map)
}
#[cfg(feature = "deserialize_in_place")] #[cfg(feature = "deserialize_in_place")]
fn deserialize_map_in_place( fn deserialize_map_in_place(
params: &Parameters, params: &Parameters,