Skip to content

Commit 83b1a3d

Browse files
authored
Merge pull request #2443 from Mingun/deserialize-in-place
Simplify code in deserialize_in_place_struct and implement #2387 for in-place case
2 parents 0c36783 + 878110a commit 83b1a3d

File tree

1 file changed

+58
-124
lines changed

1 file changed

+58
-124
lines changed

serde_derive/src/de.rs

+58-124
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,10 @@ fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<St
324324

325325
let code = match &cont.data {
326326
Data::Struct(Style::Struct, fields) => {
327-
deserialize_struct_in_place(None, params, fields, &cont.attrs, None)?
327+
deserialize_struct_in_place(params, fields, &cont.attrs)?
328328
}
329329
Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => {
330-
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
330+
deserialize_tuple_in_place(params, fields, &cont.attrs)
331331
}
332332
Data::Enum(_) | Data::Struct(Style::Unit, _) => {
333333
return None;
@@ -582,11 +582,9 @@ fn deserialize_tuple(
582582

583583
#[cfg(feature = "deserialize_in_place")]
584584
fn deserialize_tuple_in_place(
585-
variant_ident: Option<syn::Ident>,
586585
params: &Parameters,
587586
fields: &[Field],
588587
cattrs: &attr::Container,
589-
deserializer: Option<TokenStream>,
590588
) -> Fragment {
591589
assert!(!cattrs.has_flatten());
592590

@@ -600,17 +598,25 @@ fn deserialize_tuple_in_place(
600598
split_with_de_lifetime(params);
601599
let delife = params.borrowed.de_lifetime();
602600

603-
let is_enum = variant_ident.is_some();
604-
let expecting = match variant_ident {
605-
Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident),
606-
None => format!("tuple struct {}", params.type_name()),
607-
};
601+
let expecting = format!("tuple struct {}", params.type_name());
608602
let expecting = cattrs.expecting().unwrap_or(&expecting);
609603

610604
let nfields = fields.len();
611605

612-
let visit_newtype_struct = if !is_enum && nfields == 1 {
613-
Some(deserialize_newtype_struct_in_place(params, &fields[0]))
606+
let visit_newtype_struct = if nfields == 1 {
607+
// We do not generate deserialize_in_place if every field has a
608+
// deserialize_with.
609+
assert!(fields[0].attrs.deserialize_with().is_none());
610+
611+
Some(quote! {
612+
#[inline]
613+
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
614+
where
615+
__E: _serde::Deserializer<#delife>,
616+
{
617+
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
618+
}
619+
})
614620
} else {
615621
None
616622
};
@@ -624,15 +630,10 @@ fn deserialize_tuple_in_place(
624630
}
625631
};
626632

627-
let dispatch = if let Some(deserializer) = deserializer {
628-
quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #field_count, #visitor_expr))
629-
} else if is_enum {
630-
quote!(_serde::de::VariantAccess::tuple_variant(__variant, #field_count, #visitor_expr))
631-
} else if nfields == 1 {
632-
let type_name = cattrs.name().deserialize_name();
633+
let type_name = cattrs.name().deserialize_name();
634+
let dispatch = if nfields == 1 {
633635
quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
634636
} else {
635-
let type_name = cattrs.name().deserialize_name();
636637
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr))
637638
};
638639

@@ -918,25 +919,6 @@ fn deserialize_newtype_struct(
918919
}
919920
}
920921

921-
#[cfg(feature = "deserialize_in_place")]
922-
fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream {
923-
// We do not generate deserialize_in_place if every field has a
924-
// deserialize_with.
925-
assert!(field.attrs.deserialize_with().is_none());
926-
927-
let delife = params.borrowed.de_lifetime();
928-
929-
quote! {
930-
#[inline]
931-
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
932-
where
933-
__E: _serde::Deserializer<#delife>,
934-
{
935-
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
936-
}
937-
}
938-
}
939-
940922
enum StructForm<'a> {
941923
Struct,
942924
/// Contains a variant name
@@ -1133,14 +1115,10 @@ fn deserialize_struct(
11331115

11341116
#[cfg(feature = "deserialize_in_place")]
11351117
fn deserialize_struct_in_place(
1136-
variant_ident: Option<syn::Ident>,
11371118
params: &Parameters,
11381119
fields: &[Field],
11391120
cattrs: &attr::Container,
1140-
deserializer: Option<TokenStream>,
11411121
) -> Option<Fragment> {
1142-
let is_enum = variant_ident.is_some();
1143-
11441122
// for now we do not support in_place deserialization for structs that
11451123
// are represented as map.
11461124
if cattrs.has_flatten() {
@@ -1152,58 +1130,40 @@ fn deserialize_struct_in_place(
11521130
split_with_de_lifetime(params);
11531131
let delife = params.borrowed.de_lifetime();
11541132

1155-
let expecting = match variant_ident {
1156-
Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
1157-
None => format!("struct {}", params.type_name()),
1158-
};
1133+
let expecting = format!("struct {}", params.type_name());
11591134
let expecting = cattrs.expecting().unwrap_or(&expecting);
11601135

1161-
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
1162-
1163-
let (field_visitor, fields_stmt, visit_map) =
1164-
deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs);
1165-
1166-
let field_visitor = Stmts(field_visitor);
1167-
let fields_stmt = Stmts(fields_stmt);
1168-
let visit_map = Stmts(visit_map);
1136+
let field_names_idents: Vec<_> = fields
1137+
.iter()
1138+
.enumerate()
1139+
.filter(|&(_, field)| !field.attrs.skip_deserializing())
1140+
.map(|(i, field)| {
1141+
(
1142+
field.attrs.name().deserialize_name(),
1143+
field_i(i),
1144+
field.attrs.aliases(),
1145+
)
1146+
})
1147+
.collect();
11691148

1170-
let visitor_expr = quote! {
1171-
__Visitor {
1172-
place: __place,
1173-
lifetime: _serde::__private::PhantomData,
1174-
}
1175-
};
1176-
let dispatch = if let Some(deserializer) = deserializer {
1177-
quote! {
1178-
_serde::Deserializer::deserialize_any(#deserializer, #visitor_expr)
1179-
}
1180-
} else if is_enum {
1181-
quote! {
1182-
_serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
1183-
}
1184-
} else {
1185-
let type_name = cattrs.name().deserialize_name();
1186-
quote! {
1187-
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
1188-
}
1189-
};
1149+
let field_visitor = Stmts(deserialize_generated_identifier(
1150+
&field_names_idents,
1151+
cattrs,
1152+
false,
1153+
None,
1154+
));
11901155

1191-
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
1192-
let visitor_var = if all_skipped {
1156+
let mut_seq = if field_names_idents.is_empty() {
11931157
quote!(_)
11941158
} else {
11951159
quote!(mut __seq)
11961160
};
1197-
1198-
let visit_seq = quote! {
1199-
#[inline]
1200-
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error>
1201-
where
1202-
__A: _serde::de::SeqAccess<#delife>,
1203-
{
1204-
#visit_seq
1205-
}
1206-
};
1161+
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
1162+
let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs));
1163+
let field_names = field_names_idents
1164+
.iter()
1165+
.flat_map(|(_, _, aliases)| aliases);
1166+
let type_name = cattrs.name().deserialize_name();
12071167

12081168
let in_place_impl_generics = de_impl_generics.in_place();
12091169
let in_place_ty_generics = de_ty_generics.in_place();
@@ -1225,7 +1185,13 @@ fn deserialize_struct_in_place(
12251185
_serde::__private::Formatter::write_str(__formatter, #expecting)
12261186
}
12271187

1228-
#visit_seq
1188+
#[inline]
1189+
fn visit_seq<__A>(self, #mut_seq: __A) -> _serde::__private::Result<Self::Value, __A::Error>
1190+
where
1191+
__A: _serde::de::SeqAccess<#delife>,
1192+
{
1193+
#visit_seq
1194+
}
12291195

12301196
#[inline]
12311197
fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
@@ -1236,9 +1202,13 @@ fn deserialize_struct_in_place(
12361202
}
12371203
}
12381204

1239-
#fields_stmt
1205+
#[doc(hidden)]
1206+
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
12401207

1241-
#dispatch
1208+
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, __Visitor {
1209+
place: __place,
1210+
lifetime: _serde::__private::PhantomData,
1211+
})
12421212
})
12431213
}
12441214

@@ -2707,42 +2677,6 @@ fn deserialize_map(
27072677
}
27082678
}
27092679

2710-
#[cfg(feature = "deserialize_in_place")]
2711-
fn deserialize_struct_as_struct_in_place_visitor(
2712-
params: &Parameters,
2713-
fields: &[Field],
2714-
cattrs: &attr::Container,
2715-
) -> (Fragment, Fragment, Fragment) {
2716-
assert!(!cattrs.has_flatten());
2717-
2718-
let field_names_idents: Vec<_> = fields
2719-
.iter()
2720-
.enumerate()
2721-
.filter(|&(_, field)| !field.attrs.skip_deserializing())
2722-
.map(|(i, field)| {
2723-
(
2724-
field.attrs.name().deserialize_name(),
2725-
field_i(i),
2726-
field.attrs.aliases(),
2727-
)
2728-
})
2729-
.collect();
2730-
2731-
let fields_stmt = {
2732-
let field_names = field_names_idents.iter().map(|(name, _, _)| name);
2733-
quote_block! {
2734-
#[doc(hidden)]
2735-
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
2736-
}
2737-
};
2738-
2739-
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
2740-
2741-
let visit_map = deserialize_map_in_place(params, fields, cattrs);
2742-
2743-
(field_visitor, fields_stmt, visit_map)
2744-
}
2745-
27462680
#[cfg(feature = "deserialize_in_place")]
27472681
fn deserialize_map_in_place(
27482682
params: &Parameters,

0 commit comments

Comments
 (0)