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