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