From d7566cd999849ff13d2ca2d0eb2cca4ddb2c3039 Mon Sep 17 00:00:00 2001 From: Jonas Bushart Date: Wed, 16 Aug 2023 21:21:25 +0200 Subject: [PATCH] Cleanup deserialization macros The macros for creating the map deserialization code were wrong. They did not properlly account for the hasher argument. Remove the de::foreach_map! macro and replace it with the already existing de::foreach_map_create! one that does this better. --- serde_with/src/de/duplicates.rs | 16 ++++----- serde_with/src/de/impls.rs | 61 +++++++++++++++------------------ 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/serde_with/src/de/duplicates.rs b/serde_with/src/de/duplicates.rs index 8aa23592..ed54746d 100644 --- a/serde_with/src/de/duplicates.rs +++ b/serde_with/src/de/duplicates.rs @@ -1,4 +1,4 @@ -use super::impls::{foreach_map_create, foreach_set_create}; +use super::impls::{foreach_map, foreach_set_create}; use crate::{ duplicate_key_impls::{ DuplicateInsertsFirstWinsMap, DuplicateInsertsLastWinsSet, PreventDuplicateInsertsMap, @@ -75,14 +75,14 @@ where #[cfg(feature = "alloc")] macro_rules! set_impl { ( - $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >, + $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)? $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >, $with_capacity:expr, $append:ident ) => { impl<'de, T, TAs $(, $typaram)*> DeserializeAs<'de, $ty> for SetPreventDuplicates where TAs: DeserializeAs<'de, T>, - $(T: $tbound1 $(+ $tbound2)*,)* + $(T: $tbound1 $(+ $tbound2)*,)? $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> @@ -98,7 +98,7 @@ macro_rules! set_impl { impl<'de, T, TAs $(, $typaram)*> DeserializeAs<'de, $ty> for SetLastValueWins where TAs: DeserializeAs<'de, T>, - $(T: $tbound1 $(+ $tbound2)*,)* + $(T: $tbound1 $(+ $tbound2)*,)? $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> @@ -180,7 +180,7 @@ where #[cfg(feature = "alloc")] macro_rules! map_impl { ( - $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, + $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)?, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $with_capacity:expr ) => { impl<'de, K, V, KAs, VAs $(, $typaram)*> DeserializeAs<'de, $ty> @@ -188,7 +188,7 @@ macro_rules! map_impl { where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, - $(K: $kbound1 $(+ $kbound2)*,)* + $(K: $kbound1 $(+ $kbound2)*,)? $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> @@ -210,7 +210,7 @@ macro_rules! map_impl { where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, - $(K: $kbound1 $(+ $kbound2)*,)* + $(K: $kbound1 $(+ $kbound2)*,)? $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> @@ -224,4 +224,4 @@ macro_rules! map_impl { } }; } -foreach_map_create!(map_impl); +foreach_map!(map_impl); diff --git a/serde_with/src/de/impls.rs b/serde_with/src/de/impls.rs index 8c7026c8..960bf94d 100644 --- a/serde_with/src/de/impls.rs +++ b/serde_with/src/de/impls.rs @@ -13,22 +13,6 @@ use indexmap_2::{IndexMap as IndexMap2, IndexSet as IndexSet2}; type BoxedSlice = Box<[T]>; macro_rules! foreach_map { - ($m:ident) => { - #[cfg(feature = "alloc")] - $m!(BTreeMap); - #[cfg(feature = "std")] - $m!(HashMap); - #[cfg(all(feature = "std", feature = "hashbrown_0_14"))] - $m!(HashbrownMap014); - #[cfg(all(feature = "std", feature = "indexmap_1"))] - $m!(IndexMap); - #[cfg(all(feature = "std", feature = "indexmap_2"))] - $m!(IndexMap2); - }; -} -pub(crate) use foreach_map; - -macro_rules! foreach_map_create { ($m:ident) => { #[cfg(feature = "alloc")] $m!(BTreeMap, (|_size| BTreeMap::new())); @@ -54,7 +38,7 @@ macro_rules! foreach_map_create { ); }; } -pub(crate) use foreach_map_create; +pub(crate) use foreach_map; macro_rules! foreach_set { ($m:ident) => { @@ -395,7 +379,7 @@ where #[cfg(feature = "alloc")] macro_rules! seq_impl { ( - $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >, + $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)? $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >, $with_capacity:expr, $append:ident ) => { @@ -406,7 +390,7 @@ macro_rules! seq_impl { impl<'de, T, U $(, $typaram)*> DeserializeAs<'de, $ty> for $ty where U: DeserializeAs<'de, T>, - $(T: $tbound1 $(+ $tbound2)*,)* + $(T: $tbound1 $(+ $tbound2)*,)? $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> @@ -420,7 +404,7 @@ macro_rules! seq_impl { impl<'de, T, U $(, $typaram)*> Visitor<'de> for SeqVisitor where U: DeserializeAs<'de, T>, - $(T: $tbound1 $(+ $tbound2)*,)* + $(T: $tbound1 $(+ $tbound2)*,)? $($typaram: $bound1 $(+ $bound2)*),* { type Value = $ty; @@ -515,7 +499,7 @@ macro_rules! map_impl { } } } -foreach_map_create!(map_impl); +foreach_map!(map_impl); macro_rules! tuple_impl { ($len:literal $($n:tt $t:ident $tas:ident)+) => { @@ -584,28 +568,34 @@ tuple_impl!(16 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 #[cfg(feature = "alloc")] macro_rules! map_as_tuple_seq_intern { - ($tyorig:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $ty:ident <(KAs, VAs)>) => { - impl<'de, K, KAs, V, VAs> DeserializeAs<'de, $tyorig> for $ty<(KAs, VAs)> + ( + $tyorig:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)?, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, + $with_capacity:expr, + $ty:ident <(KAs, VAs)> + ) => { + impl<'de, K, KAs, V, VAs $(, $typaram)*> DeserializeAs<'de, $tyorig> for $ty<(KAs, VAs)> where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, - $(K: $kbound1 $(+ $kbound2)*,)* + $(K: $kbound1 $(+ $kbound2)*,)? + $($typaram: $bound1 $(+ $bound2)*,)* { - fn deserialize_as(deserializer: D) -> Result<$tyorig, D::Error> + fn deserialize_as(deserializer: D) -> Result<$tyorig, D::Error> where D: Deserializer<'de>, { - struct SeqVisitor { - marker: PhantomData<(K, KAs, V, VAs)>, + struct SeqVisitor { + marker: PhantomData<(K, KAs, V, VAs $(, $typaram)*)>, } - impl<'de, K, KAs, V, VAs> Visitor<'de> for SeqVisitor + impl<'de, K, KAs, V, VAs $(, $typaram)*> Visitor<'de> for SeqVisitor where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, - $(K: $kbound1 $(+ $kbound2)*,)* + $(K: $kbound1 $(+ $kbound2)*,)? + $($typaram: $bound1 $(+ $bound2)*,)* { - type Value = $tyorig; + type Value = $tyorig; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") @@ -628,7 +618,7 @@ macro_rules! map_as_tuple_seq_intern { } } - let visitor = SeqVisitor:: { + let visitor = SeqVisitor:: { marker: PhantomData, }; deserializer.deserialize_seq(visitor) @@ -638,10 +628,13 @@ macro_rules! map_as_tuple_seq_intern { } #[cfg(feature = "alloc")] macro_rules! map_as_tuple_seq { - ($tyorig:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >) => { - map_as_tuple_seq_intern!($tyorig < K $(: $kbound1 $(+ $kbound2)*)* , V $(, $typaram : $bound1 $(+ $bound2)*)* > , Seq<(KAs, VAs)>); + ( + $tyorig:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)?, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, + $with_capacity:expr + ) => { + map_as_tuple_seq_intern!($tyorig < K $(: $kbound1 $(+ $kbound2)*)? , V $(, $typaram : $bound1 $(+ $bound2)*)* >, $with_capacity, Seq<(KAs, VAs)>); #[cfg(feature = "alloc")] - map_as_tuple_seq_intern!($tyorig < K $(: $kbound1 $(+ $kbound2)*)* , V $(, $typaram : $bound1 $(+ $bound2)*)* >, Vec<(KAs, VAs)>); + map_as_tuple_seq_intern!($tyorig < K $(: $kbound1 $(+ $kbound2)*)? , V $(, $typaram : $bound1 $(+ $bound2)*)* >, $with_capacity, Vec<(KAs, VAs)>); } } foreach_map!(map_as_tuple_seq);