Skip to main content

serde_with/de/
skip_error.rs

1use super::impls::macros::foreach_map;
2use crate::prelude::*;
3#[cfg(feature = "hashbrown_0_14")]
4use hashbrown_0_14::HashMap as HashbrownMap014;
5#[cfg(feature = "hashbrown_0_15")]
6use hashbrown_0_15::HashMap as HashbrownMap015;
7#[cfg(feature = "hashbrown_0_16")]
8use hashbrown_0_16::HashMap as HashbrownMap016;
9#[cfg(feature = "hashbrown_0_17")]
10use hashbrown_0_17::HashMap as HashbrownMap017;
11#[cfg(feature = "indexmap_1")]
12use indexmap_1::IndexMap;
13#[cfg(feature = "indexmap_2")]
14use indexmap_2::IndexMap as IndexMap2;
15
16enum GoodOrError<T, TAs, I> {
17    Good(T),
18    // Only here to consume the TAs,I generics
19    Error(PhantomData<(TAs, I)>),
20}
21
22impl<'de, T, TAs, I> Deserialize<'de> for GoodOrError<T, TAs, I>
23where
24    TAs: DeserializeAs<'de, T>,
25    I: InspectError,
26{
27    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
28    where
29        D: Deserializer<'de>,
30    {
31        let is_hr = deserializer.is_human_readable();
32        let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?;
33
34        Ok(
35            match <DeserializeAsWrap<T, TAs>>::deserialize(content::de::ContentDeserializer::<
36                D::Error,
37            >::new(content, is_hr))
38            {
39                Ok(elem) => GoodOrError::Good(elem.into_inner()),
40                Err(e) => {
41                    I::inspect_error(e);
42                    GoodOrError::Error(PhantomData)
43                }
44            },
45        )
46    }
47}
48
49impl<'de, T, U, I> DeserializeAs<'de, Vec<T>> for VecSkipError<U, I>
50where
51    U: DeserializeAs<'de, T>,
52    I: InspectError,
53{
54    fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
55    where
56        D: Deserializer<'de>,
57    {
58        struct SeqVisitor<T, U, I>(PhantomData<(T, U, I)>);
59
60        impl<'de, T, TAs, I> Visitor<'de> for SeqVisitor<T, TAs, I>
61        where
62            I: InspectError,
63            TAs: DeserializeAs<'de, T>,
64        {
65            type Value = Vec<T>;
66
67            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
68                formatter.write_str("a sequence")
69            }
70
71            fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
72            where
73                A: SeqAccess<'de>,
74            {
75                utils::SeqIter::new(seq)
76                    .filter_map(|res: Result<GoodOrError<T, TAs, I>, A::Error>| match res {
77                        Ok(GoodOrError::Good(value)) => Some(Ok(value)),
78                        Ok(GoodOrError::Error(_)) => None,
79                        Err(err) => Some(Err(err)),
80                    })
81                    .collect()
82            }
83        }
84
85        let visitor = SeqVisitor::<T, U, I>(PhantomData);
86        deserializer.deserialize_seq(visitor)
87    }
88}
89
90struct MapSkipErrorVisitor<MAP, K, KAs, V, VAs, I>(PhantomData<(MAP, K, KAs, V, VAs, I)>);
91
92impl<'de, MAP, K, KAs, V, VAs, I> Visitor<'de> for MapSkipErrorVisitor<MAP, K, KAs, V, VAs, I>
93where
94    MAP: FromIterator<(K, V)>,
95    KAs: DeserializeAs<'de, K>,
96    VAs: DeserializeAs<'de, V>,
97    I: InspectError,
98{
99    type Value = MAP;
100
101    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
102        formatter.write_str("a map")
103    }
104
105    #[inline]
106    fn visit_map<A>(self, access: A) -> Result<Self::Value, A::Error>
107    where
108        A: MapAccess<'de>,
109    {
110        type KVPair<K, KAs, V, VAs, I> = (GoodOrError<K, KAs, I>, GoodOrError<V, VAs, I>);
111        utils::MapIter::new(access)
112            .filter_map(
113                |res: Result<KVPair<K, KAs, V, VAs, I>, A::Error>| match res {
114                    Ok((GoodOrError::Good(key), GoodOrError::Good(value))) => {
115                        Some(Ok((key, value)))
116                    }
117                    Ok(_) => None,
118                    Err(err) => Some(Err(err)),
119                },
120            )
121            .collect()
122    }
123}
124
125#[cfg(feature = "alloc")]
126macro_rules! map_impl {
127    (
128        $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)?, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
129        $with_capacity:expr
130    ) => {
131        impl<'de, K, V, KAs, VAs, I $(, $typaram)*> DeserializeAs<'de, $ty<K, V $(, $typaram)*>>
132            for MapSkipError<KAs, VAs, I>
133        where
134            KAs: DeserializeAs<'de, K>,
135            VAs: DeserializeAs<'de, V>,
136            I: InspectError,
137            $(K: $kbound1 $(+ $kbound2)*,)?
138            $($typaram: $bound1 $(+ $bound2)*),*
139        {
140            fn deserialize_as<D>(deserializer: D) -> Result<$ty<K, V $(, $typaram)*>, D::Error>
141            where
142                D: Deserializer<'de>,
143            {
144                deserializer.deserialize_map(MapSkipErrorVisitor::<
145                    $ty<K, V $(, $typaram)*>,
146                    K,
147                    KAs,
148                    V,
149                    VAs,
150                    I,
151                >(PhantomData))
152            }
153        }
154    };
155}
156foreach_map!(map_impl);