Skip to main content

serde_with/de/
duplicates.rs

1use super::impls::macros::{foreach_map, foreach_set};
2use crate::{
3    duplicate_key_impls::{
4        DuplicateInsertsFirstWinsMap, DuplicateInsertsLastWinsSet, PreventDuplicateInsertsMap,
5        PreventDuplicateInsertsSet,
6    },
7    prelude::*,
8};
9#[cfg(feature = "hashbrown_0_14")]
10use hashbrown_0_14::{HashMap as HashbrownMap014, HashSet as HashbrownSet014};
11#[cfg(feature = "hashbrown_0_15")]
12use hashbrown_0_15::{HashMap as HashbrownMap015, HashSet as HashbrownSet015};
13#[cfg(feature = "hashbrown_0_16")]
14use hashbrown_0_16::{HashMap as HashbrownMap016, HashSet as HashbrownSet016};
15#[cfg(feature = "hashbrown_0_17")]
16use hashbrown_0_17::{HashMap as HashbrownMap017, HashSet as HashbrownSet017};
17#[cfg(feature = "indexmap_1")]
18use indexmap_1::{IndexMap, IndexSet};
19#[cfg(feature = "indexmap_2")]
20use indexmap_2::{IndexMap as IndexMap2, IndexSet as IndexSet2};
21
22struct SetPreventDuplicatesVisitor<SET, T, TAs>(PhantomData<(SET, T, TAs)>);
23
24impl<'de, SET, T, TAs> Visitor<'de> for SetPreventDuplicatesVisitor<SET, T, TAs>
25where
26    SET: PreventDuplicateInsertsSet<T>,
27    TAs: DeserializeAs<'de, T>,
28{
29    type Value = SET;
30
31    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32        formatter.write_str("a sequence")
33    }
34
35    #[inline]
36    fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
37    where
38        A: SeqAccess<'de>,
39    {
40        let mut values = Self::Value::new(access.size_hint());
41
42        while let Some(value) = access.next_element::<DeserializeAsWrap<T, TAs>>()? {
43            if !values.insert(value.into_inner()) {
44                return Err(DeError::custom("invalid entry: found duplicate value"));
45            };
46        }
47
48        Ok(values)
49    }
50}
51
52struct SetLastValueWinsVisitor<SET, T, TAs>(PhantomData<(SET, T, TAs)>);
53
54impl<'de, SET, T, TAs> Visitor<'de> for SetLastValueWinsVisitor<SET, T, TAs>
55where
56    SET: DuplicateInsertsLastWinsSet<T>,
57    TAs: DeserializeAs<'de, T>,
58{
59    type Value = SET;
60
61    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
62        formatter.write_str("a sequence")
63    }
64
65    #[inline]
66    fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
67    where
68        A: SeqAccess<'de>,
69    {
70        let mut values = Self::Value::new(access.size_hint());
71
72        while let Some(value) = access.next_element::<DeserializeAsWrap<T, TAs>>()? {
73            values.replace(value.into_inner());
74        }
75
76        Ok(values)
77    }
78}
79
80#[cfg(feature = "alloc")]
81macro_rules! set_impl {
82    (
83        $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)? $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >,
84        $with_capacity:expr,
85        $append:ident
86    ) => {
87        impl<'de, T, TAs $(, $typaram)*> DeserializeAs<'de, $ty<T $(, $typaram)*>> for SetPreventDuplicates<TAs>
88        where
89            TAs: DeserializeAs<'de, T>,
90            $(T: $tbound1 $(+ $tbound2)*,)?
91            $($typaram: $bound1 $(+ $bound2)*),*
92        {
93            fn deserialize_as<D>(deserializer: D) -> Result<$ty<T $(, $typaram)*>, D::Error>
94            where
95                D: Deserializer<'de>,
96            {
97                deserializer.deserialize_seq(SetPreventDuplicatesVisitor::<$ty<T $(, $typaram)*>, T, TAs>(
98                    PhantomData,
99                ))
100            }
101        }
102
103        impl<'de, T, TAs $(, $typaram)*> DeserializeAs<'de, $ty<T $(, $typaram)*>> for SetLastValueWins<TAs>
104        where
105            TAs: DeserializeAs<'de, T>,
106            $(T: $tbound1 $(+ $tbound2)*,)?
107            $($typaram: $bound1 $(+ $bound2)*),*
108        {
109            fn deserialize_as<D>(deserializer: D) -> Result<$ty<T $(, $typaram)*>, D::Error>
110            where
111                D: Deserializer<'de>,
112            {
113                deserializer
114                    .deserialize_seq(SetLastValueWinsVisitor::<$ty<T $(, $typaram)*>, T, TAs>(PhantomData))
115            }
116        }
117    }
118}
119foreach_set!(set_impl);
120
121struct MapPreventDuplicatesVisitor<MAP, K, KAs, V, VAs>(PhantomData<(MAP, K, KAs, V, VAs)>);
122
123impl<'de, MAP, K, KAs, V, VAs> Visitor<'de> for MapPreventDuplicatesVisitor<MAP, K, KAs, V, VAs>
124where
125    MAP: PreventDuplicateInsertsMap<K, V>,
126    KAs: DeserializeAs<'de, K>,
127    VAs: DeserializeAs<'de, V>,
128{
129    type Value = MAP;
130
131    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
132        formatter.write_str("a map")
133    }
134
135    #[inline]
136    fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
137    where
138        A: MapAccess<'de>,
139    {
140        let mut values = Self::Value::new(access.size_hint());
141
142        while let Some((key, value)) =
143            access.next_entry::<DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>>()?
144        {
145            if !values.insert(key.into_inner(), value.into_inner()) {
146                return Err(DeError::custom("invalid entry: found duplicate key"));
147            };
148        }
149
150        Ok(values)
151    }
152}
153
154struct MapFirstKeyWinsVisitor<MAP, K, KAs, V, VAs>(PhantomData<(MAP, K, KAs, V, VAs)>);
155
156impl<'de, MAP, K, KAs, V, VAs> Visitor<'de> for MapFirstKeyWinsVisitor<MAP, K, KAs, V, VAs>
157where
158    MAP: DuplicateInsertsFirstWinsMap<K, V>,
159    KAs: DeserializeAs<'de, K>,
160    VAs: DeserializeAs<'de, V>,
161{
162    type Value = MAP;
163
164    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
165        formatter.write_str("a map")
166    }
167
168    #[inline]
169    fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
170    where
171        A: MapAccess<'de>,
172    {
173        let mut values = Self::Value::new(access.size_hint());
174
175        while let Some((key, value)) =
176            access.next_entry::<DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>>()?
177        {
178            values.insert(key.into_inner(), value.into_inner());
179        }
180
181        Ok(values)
182    }
183}
184
185#[cfg(feature = "alloc")]
186macro_rules! map_impl {
187    (
188        $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)?, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
189        $with_capacity:expr
190    ) => {
191        impl<'de, K, V, KAs, VAs $(, $typaram)*> DeserializeAs<'de, $ty<K, V $(, $typaram)*>>
192            for MapPreventDuplicates<KAs, VAs>
193        where
194            KAs: DeserializeAs<'de, K>,
195            VAs: DeserializeAs<'de, V>,
196            $(K: $kbound1 $(+ $kbound2)*,)?
197            $($typaram: $bound1 $(+ $bound2)*),*
198        {
199            fn deserialize_as<D>(deserializer: D) -> Result<$ty<K, V $(, $typaram)*>, D::Error>
200            where
201                D: Deserializer<'de>,
202            {
203                deserializer.deserialize_map(MapPreventDuplicatesVisitor::<
204                    $ty<K, V $(, $typaram)*>,
205                    K,
206                    KAs,
207                    V,
208                    VAs,
209                >(PhantomData))
210            }
211        }
212
213        impl<'de, K, V, KAs, VAs $(, $typaram)*> DeserializeAs<'de, $ty<K, V $(, $typaram)*>>
214            for MapFirstKeyWins<KAs, VAs>
215        where
216            KAs: DeserializeAs<'de, K>,
217            VAs: DeserializeAs<'de, V>,
218            $(K: $kbound1 $(+ $kbound2)*,)?
219            $($typaram: $bound1 $(+ $bound2)*),*
220        {
221            fn deserialize_as<D>(deserializer: D) -> Result<$ty<K, V $(, $typaram)*>, D::Error>
222            where
223                D: Deserializer<'de>,
224            {
225                deserializer.deserialize_map(MapFirstKeyWinsVisitor::<$ty<K, V $(, $typaram)*>, K, KAs, V, VAs>(
226                    PhantomData,
227                ))
228            }
229        }
230    };
231}
232foreach_map!(map_impl);