mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-02 15:25:38 +00:00
Do not emit an in-place deserialization path for struct as map
This commit is contained in:
parent
61b167be9a
commit
d44f12907b
@ -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 = ¶ms.this;
|
let this = ¶ms.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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user