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