From 07374746405e350e2ddcf31d6711877d79e37183 Mon Sep 17 00:00:00 2001 From: Mingun Date: Thu, 22 Oct 2020 10:18:27 +0500 Subject: [PATCH] Allow field identifiers be any numbers if `#[serde(other)]` is used Thus behavior synchronized between string/bytes identifiers and numeric identifiers --- serde_derive/src/de.rs | 37 ++++++++++++++++--- test_suite/tests/expand/de_enum.expanded.rs | 10 +---- .../tests/expand/default_ty_param.expanded.rs | 10 +---- .../tests/expand/generic_enum.expanded.rs | 5 +-- .../tests/expand/generic_struct.expanded.rs | 10 +---- test_suite/tests/expand/lifetimes.expanded.rs | 10 +---- test_suite/tests/expand/named_map.expanded.rs | 10 +---- 7 files changed, 42 insertions(+), 50 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 1f5733a6..3267a3e5 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1940,6 +1940,15 @@ fn deserialize_generated_identifier( } } +/// Generates `Deserialize::deserialize` body for +/// ```ignore +/// #[serde(field_identifier)] +/// enum Field { +/// } +/// #[serde(variant_identifier)] +/// enum Variant { +/// } +/// ``` fn deserialize_custom_identifier( params: &Parameters, variants: &[Variant], @@ -1957,6 +1966,8 @@ fn deserialize_custom_identifier( let (ordinary, fallthrough) = if let Some(last) = variants.last() { let last_ident = &last.ident; if last.attrs.other() { + // Processes `#[serde(other)]` attribute. It always belongs to the last variant + // (checked in `check_identifier`), so all other are ordinal variants let ordinary = &variants[..variants.len() - 1]; let fallthrough = quote!(_serde::export::Ok(#this::#last_ident)); (ordinary, Some(fallthrough)) @@ -1976,6 +1987,10 @@ fn deserialize_custom_identifier( (variants, None) }; + // List of tuples: + // - field or variant name in the expected messages + // - information about field/variant + // - list of alternate names of the field/variant let names_idents: Vec<_> = ordinary .iter() .map(|variant| { @@ -2106,7 +2121,7 @@ fn deserialize_identifier( (None, None, None, None) }; - let fallthrough_arm = if let Some(fallthrough) = fallthrough { + let fallthrough_arm = if let Some(fallthrough) = fallthrough.clone() { fallthrough } else if is_variant { quote! { @@ -2118,8 +2133,19 @@ fn deserialize_identifier( } }; + let u64_fallthrough_arm = if let Some(fallthrough) = fallthrough { + fallthrough + } else { + let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len()); + quote! { + _serde::export::Err(_serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &#fallthrough_msg, + )) + } + }; + let variant_indices = 0_u64..; - let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len()); let visit_other = if collect_other_fields { quote! { fn visit_bool<__E>(self, __value: bool) -> _serde::export::Result @@ -2254,10 +2280,9 @@ fn deserialize_identifier( #( #variant_indices => _serde::export::Ok(#main_constructors), )* - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &#fallthrough_msg, - )) + _ => { + #u64_fallthrough_arm + } } } } diff --git a/test_suite/tests/expand/de_enum.expanded.rs b/test_suite/tests/expand/de_enum.expanded.rs index a4ba2491..3fad0ded 100644 --- a/test_suite/tests/expand/de_enum.expanded.rs +++ b/test_suite/tests/expand/de_enum.expanded.rs @@ -563,10 +563,7 @@ const _: () = { 1u64 => _serde::export::Ok(__Field::__field1), 2u64 => _serde::export::Ok(__Field::__field2), 3u64 => _serde::export::Ok(__Field::__field3), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 4", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>( @@ -1066,10 +1063,7 @@ const _: () = { 1u64 => _serde::export::Ok(__Field::__field1), 2u64 => _serde::export::Ok(__Field::__field2), 3u64 => _serde::export::Ok(__Field::__field3), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 4", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>( diff --git a/test_suite/tests/expand/default_ty_param.expanded.rs b/test_suite/tests/expand/default_ty_param.expanded.rs index 8aaa3ab4..ee0f0666 100644 --- a/test_suite/tests/expand/default_ty_param.expanded.rs +++ b/test_suite/tests/expand/default_ty_param.expanded.rs @@ -74,10 +74,7 @@ const _: () = { { match __value { 0u64 => _serde::export::Ok(__Field::__field0), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 1", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>(self, __value: &str) -> _serde::export::Result @@ -250,10 +247,7 @@ const _: () = { { match __value { 0u64 => _serde::export::Ok(__Field::__field0), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 1", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>(self, __value: &str) -> _serde::export::Result diff --git a/test_suite/tests/expand/generic_enum.expanded.rs b/test_suite/tests/expand/generic_enum.expanded.rs index add7c510..88f441b3 100644 --- a/test_suite/tests/expand/generic_enum.expanded.rs +++ b/test_suite/tests/expand/generic_enum.expanded.rs @@ -347,10 +347,7 @@ const _: () = { match __value { 0u64 => _serde::export::Ok(__Field::__field0), 1u64 => _serde::export::Ok(__Field::__field1), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 2", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>( diff --git a/test_suite/tests/expand/generic_struct.expanded.rs b/test_suite/tests/expand/generic_struct.expanded.rs index 59d2e51d..ea3059de 100644 --- a/test_suite/tests/expand/generic_struct.expanded.rs +++ b/test_suite/tests/expand/generic_struct.expanded.rs @@ -70,10 +70,7 @@ const _: () = { { match __value { 0u64 => _serde::export::Ok(__Field::__field0), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 1", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>(self, __value: &str) -> _serde::export::Result @@ -246,10 +243,7 @@ const _: () = { { match __value { 0u64 => _serde::export::Ok(__Field::__field0), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 1", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>(self, __value: &str) -> _serde::export::Result diff --git a/test_suite/tests/expand/lifetimes.expanded.rs b/test_suite/tests/expand/lifetimes.expanded.rs index 9840d440..bab22ebe 100644 --- a/test_suite/tests/expand/lifetimes.expanded.rs +++ b/test_suite/tests/expand/lifetimes.expanded.rs @@ -235,10 +235,7 @@ const _: () = { { match __value { 0u64 => _serde::export::Ok(__Field::__field0), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 1", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>( @@ -420,10 +417,7 @@ const _: () = { { match __value { 0u64 => _serde::export::Ok(__Field::__field0), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 1", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>( diff --git a/test_suite/tests/expand/named_map.expanded.rs b/test_suite/tests/expand/named_map.expanded.rs index ce43b663..b35da683 100644 --- a/test_suite/tests/expand/named_map.expanded.rs +++ b/test_suite/tests/expand/named_map.expanded.rs @@ -97,10 +97,7 @@ const _: () = { 0u64 => _serde::export::Ok(__Field::__field0), 1u64 => _serde::export::Ok(__Field::__field1), 2u64 => _serde::export::Ok(__Field::__field2), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 3", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>(self, __value: &str) -> _serde::export::Result @@ -373,10 +370,7 @@ const _: () = { 0u64 => _serde::export::Ok(__Field::__field0), 1u64 => _serde::export::Ok(__Field::__field1), 2u64 => _serde::export::Ok(__Field::__field2), - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"field index 0 <= i < 3", - )), + _ => _serde::export::Ok(__Field::__ignore), } } fn visit_str<__E>(self, __value: &str) -> _serde::export::Result