Skip to content

Commit 2dbeefb

Browse files
authored
Merge pull request #2935 from Mingun/dedupe-adj-enums
Remove code duplication when deriving Deserialize for adjacently tagged enums
2 parents 8a3c29f + bfb020d commit 2dbeefb

1 file changed

Lines changed: 34 additions & 27 deletions

File tree

serde_derive/src/de.rs

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ fn deserialize_in_place_body(_cont: &Container, _params: &Parameters) -> Option<
352352
None
353353
}
354354

355+
/// Generates `Deserialize::deserialize` body for a type with `#[serde(transparent)]` attribute
355356
fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
356357
let fields = match &cont.data {
357358
Data::Struct(_, fields) => fields,
@@ -394,6 +395,7 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
394395
}
395396
}
396397

398+
/// Generates `Deserialize::deserialize` body for a type with `#[serde(from)]` attribute
397399
fn deserialize_from(type_from: &syn::Type) -> Fragment {
398400
quote_block! {
399401
_serde::#private::Result::map(
@@ -402,6 +404,7 @@ fn deserialize_from(type_from: &syn::Type) -> Fragment {
402404
}
403405
}
404406

407+
/// Generates `Deserialize::deserialize` body for a type with `#[serde(try_from)]` attribute
405408
fn deserialize_try_from(type_try_from: &syn::Type) -> Fragment {
406409
quote_block! {
407410
_serde::#private::Result::and_then(
@@ -410,6 +413,7 @@ fn deserialize_try_from(type_try_from: &syn::Type) -> Fragment {
410413
}
411414
}
412415

416+
/// Generates `Deserialize::deserialize` body for a `struct Unit;`
413417
fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment {
414418
let this_type = &params.this_type;
415419
let this_value = &params.this_value;
@@ -465,6 +469,7 @@ enum TupleForm<'a> {
465469
Untagged(&'a syn::Ident, TokenStream),
466470
}
467471

472+
/// Generates `Deserialize::deserialize` body for a `struct Tuple(...);` including `struct Newtype(T);`
468473
fn deserialize_tuple(
469474
params: &Parameters,
470475
fields: &[Field],
@@ -587,6 +592,7 @@ fn deserialize_tuple(
587592
}
588593
}
589594

595+
/// Generates `Deserialize::deserialize_in_place` body for a `struct Tuple(...);` including `struct Newtype(T);`
590596
#[cfg(feature = "deserialize_in_place")]
591597
fn deserialize_tuple_in_place(
592598
params: &Parameters,
@@ -937,6 +943,7 @@ enum StructForm<'a> {
937943
Untagged(&'a syn::Ident, TokenStream),
938944
}
939945

946+
/// Generates `Deserialize::deserialize` body for a `struct Struct {...}`
940947
fn deserialize_struct(
941948
params: &Parameters,
942949
fields: &[Field],
@@ -1119,6 +1126,7 @@ fn deserialize_struct(
11191126
}
11201127
}
11211128

1129+
/// Generates `Deserialize::deserialize_in_place` body for a `struct Struct {...}`
11221130
#[cfg(feature = "deserialize_in_place")]
11231131
fn deserialize_struct_in_place(
11241132
params: &Parameters,
@@ -1209,6 +1217,7 @@ fn deserialize_struct_in_place(
12091217
})
12101218
}
12111219

1220+
/// Generates `Deserialize::deserialize` body for an `enum Enum {...}`
12121221
fn deserialize_enum(
12131222
params: &Parameters,
12141223
variants: &[Variant],
@@ -1284,6 +1293,7 @@ fn prepare_enum_variant_enum(variants: &[Variant]) -> (TokenStream, Stmts) {
12841293
(variants_stmt, variant_visitor)
12851294
}
12861295

1296+
/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` without additional attributes
12871297
fn deserialize_externally_tagged_enum(
12881298
params: &Parameters,
12891299
variants: &[Variant],
@@ -1378,6 +1388,7 @@ fn deserialize_externally_tagged_enum(
13781388
}
13791389
}
13801390

1391+
/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` with `#[serde(tag)]` attribute
13811392
fn deserialize_internally_tagged_enum(
13821393
params: &Parameters,
13831394
variants: &[Variant],
@@ -1425,6 +1436,7 @@ fn deserialize_internally_tagged_enum(
14251436
}
14261437
}
14271438

1439+
/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` with `#[serde(tag, content)]` attributes
14281440
fn deserialize_adjacently_tagged_enum(
14291441
params: &Parameters,
14301442
variants: &[Variant],
@@ -1474,21 +1486,6 @@ fn deserialize_adjacently_tagged_enum(
14741486
quote! { _serde::#private::de::TagContentOtherFieldVisitor }
14751487
};
14761488

1477-
let tag_or_content = quote! {
1478-
#field_visitor_ty {
1479-
tag: #tag,
1480-
content: #content,
1481-
}
1482-
};
1483-
1484-
let variant_seed = quote! {
1485-
_serde::#private::de::AdjacentlyTaggedEnumVariantSeed::<__Field> {
1486-
enum_name: #rust_name,
1487-
variants: VARIANTS,
1488-
fields_enum: _serde::#private::PhantomData
1489-
}
1490-
};
1491-
14921489
let mut missing_content = quote! {
14931490
_serde::#private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
14941491
};
@@ -1533,11 +1530,18 @@ fn deserialize_adjacently_tagged_enum(
15331530

15341531
// Advance the map by one key, returning early in case of error.
15351532
let next_key = quote! {
1536-
_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)?
1533+
_serde::de::MapAccess::next_key_seed(&mut __map, #field_visitor_ty {
1534+
tag: #tag,
1535+
content: #content,
1536+
})?
15371537
};
15381538

15391539
let variant_from_map = quote! {
1540-
_serde::de::MapAccess::next_value_seed(&mut __map, #variant_seed)?
1540+
_serde::de::MapAccess::next_value_seed(&mut __map, _serde::#private::de::AdjacentlyTaggedEnumVariantSeed::<__Field> {
1541+
enum_name: #rust_name,
1542+
variants: VARIANTS,
1543+
fields_enum: _serde::#private::PhantomData
1544+
})?
15411545
};
15421546

15431547
// When allowing unknown fields, we want to transparently step through keys
@@ -1589,10 +1593,13 @@ fn deserialize_adjacently_tagged_enum(
15891593
}
15901594
} else {
15911595
quote! {
1592-
let __ret = match #variant_from_map {
1593-
// Deserialize the buffered content now that we know the variant.
1594-
#(#variant_arms)*
1595-
}?;
1596+
let __seed = __Seed {
1597+
variant: #variant_from_map,
1598+
marker: _serde::#private::PhantomData,
1599+
lifetime: _serde::#private::PhantomData,
1600+
};
1601+
let __deserializer = _serde::#private::de::ContentDeserializer::<__A::Error>::new(__content);
1602+
let __ret = _serde::de::DeserializeSeed::deserialize(__seed, __deserializer)?;
15961603
// Visit remaining keys, looking for duplicates.
15971604
#visit_remaining_keys
15981605
}
@@ -1605,7 +1612,7 @@ fn deserialize_adjacently_tagged_enum(
16051612

16061613
#[doc(hidden)]
16071614
struct __Seed #de_impl_generics #where_clause {
1608-
field: __Field,
1615+
variant: __Field,
16091616
marker: _serde::#private::PhantomData<#this_type #ty_generics>,
16101617
lifetime: _serde::#private::PhantomData<&#delife ()>,
16111618
}
@@ -1618,7 +1625,7 @@ fn deserialize_adjacently_tagged_enum(
16181625
where
16191626
__D: _serde::Deserializer<#delife>,
16201627
{
1621-
match self.field {
1628+
match self.variant {
16221629
#(#variant_arms)*
16231630
}
16241631
}
@@ -1658,7 +1665,7 @@ fn deserialize_adjacently_tagged_enum(
16581665
_serde::#private::Some(_serde::#private::de::TagOrContentField::Content) => {
16591666
let __ret = _serde::de::MapAccess::next_value_seed(&mut __map,
16601667
__Seed {
1661-
field: __field,
1668+
variant: __field,
16621669
marker: _serde::#private::PhantomData,
16631670
lifetime: _serde::#private::PhantomData,
16641671
})?;
@@ -1677,7 +1684,6 @@ fn deserialize_adjacently_tagged_enum(
16771684
match #next_relevant_key {
16781685
// Second key is the tag.
16791686
_serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
1680-
let __deserializer = _serde::#private::de::ContentDeserializer::<__A::Error>::new(__content);
16811687
#finish_content_then_tag
16821688
}
16831689
// Second key is a duplicate of the content.
@@ -1703,12 +1709,12 @@ fn deserialize_adjacently_tagged_enum(
17031709
{
17041710
// Visit the first element - the tag.
17051711
match _serde::de::SeqAccess::next_element(&mut __seq)? {
1706-
_serde::#private::Some(__field) => {
1712+
_serde::#private::Some(__variant) => {
17071713
// Visit the second element - the content.
17081714
match _serde::de::SeqAccess::next_element_seed(
17091715
&mut __seq,
17101716
__Seed {
1711-
field: __field,
1717+
variant: __variant,
17121718
marker: _serde::#private::PhantomData,
17131719
lifetime: _serde::#private::PhantomData,
17141720
},
@@ -1742,6 +1748,7 @@ fn deserialize_adjacently_tagged_enum(
17421748
}
17431749
}
17441750

1751+
/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` with `#[serde(untagged)]` attribute
17451752
fn deserialize_untagged_enum(
17461753
params: &Parameters,
17471754
variants: &[Variant],

0 commit comments

Comments
 (0)