xmlity/types/
iterator.rs

1//! This module contains visitors and [`Serialize`]/[`Deserialize`] implementations for iterators and common collections.
2use std::collections::{BTreeSet, HashMap, HashSet, LinkedList, VecDeque};
3use std::marker::PhantomData;
4
5use crate::de::{self, Visitor};
6use crate::ser::SerializeSeq;
7use crate::{de::SeqAccess, Deserialize, Deserializer};
8use crate::{Serialize, Serializer};
9use core::fmt;
10use std::iter::FromIterator;
11
12use super::utils::ValueOrWhitespace;
13
14/// This trait is used to decide how [`IteratorVisitor`] will deserialize a type.
15pub trait IteratorVisitorMiddleware<T> {
16    /// The output of the middleware.
17    type Output;
18
19    /// Takes in the item iterator and results in the [`IteratorVisitorMiddleware::Output`] type.
20    fn transform<I>(iter: I) -> Self::Output
21    where
22        I: IntoIterator<Item = T>;
23}
24
25impl<T, F: FromIterator<T>> IteratorVisitorMiddleware<T> for F {
26    type Output = F;
27    fn transform<I>(iter: I) -> Self::Output
28    where
29        I: IntoIterator<Item = T>,
30    {
31        F::from_iter(iter)
32    }
33}
34
35struct NoWhitespaceIter<T, O> {
36    _marker: PhantomData<(T, O)>,
37    result: O,
38}
39
40impl<'de, T: Deserialize<'de>, O: FromIterator<T>> FromIterator<ValueOrWhitespace<'de, T>>
41    for NoWhitespaceIter<T, O>
42{
43    fn from_iter<I: IntoIterator<Item = ValueOrWhitespace<'de, T>>>(iter: I) -> Self {
44        Self {
45            _marker: PhantomData,
46            result: O::from_iter(iter.into_iter().filter_map(|a| match a {
47                ValueOrWhitespace::Whitespace(_) => None,
48                ValueOrWhitespace::Value(a) => Some(a),
49            })),
50        }
51    }
52}
53
54impl<'de, T: Deserialize<'de>, O: FromIterator<T>> Deserialize<'de> for NoWhitespaceIter<T, O> {
55    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
56        reader.deserialize_seq(IteratorVisitor::<_, Self>::default())
57    }
58}
59
60/// This visitor allows for deserializing an iterator of elements, which can be useful for deserializing sequences of elements into a collection/single value.
61pub struct IteratorVisitor<T, M> {
62    _marker: PhantomData<(T, M)>,
63}
64
65impl<T, M: IteratorVisitorMiddleware<T>> IteratorVisitor<T, M> {
66    /// Creates a new [`IteratorVisitor`].
67    pub fn new() -> Self {
68        Self {
69            _marker: PhantomData,
70        }
71    }
72}
73
74impl<T, M: IteratorVisitorMiddleware<T>> Default for IteratorVisitor<T, M> {
75    fn default() -> Self {
76        Self::new()
77    }
78}
79
80impl<'de, T, M> Visitor<'de> for IteratorVisitor<T, M>
81where
82    T: Deserialize<'de>,
83    M: IteratorVisitorMiddleware<T>,
84    M::Output: de::Deserialize<'de>,
85{
86    type Value = M::Output;
87
88    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
89        write!(formatter, "a sequence of elements")
90    }
91
92    fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
93    where
94        S: SeqAccess<'de>,
95    {
96        Ok(M::transform(std::iter::from_fn(|| {
97            seq.next_element_seq::<T>().ok().flatten()
98        })))
99    }
100
101    fn visit_none<E>(self) -> Result<Self::Value, E>
102    where
103        E: de::Error,
104    {
105        Ok(M::transform(std::iter::empty()))
106    }
107}
108
109fn serialize_seq<T, S>(iter: T, serializer: S) -> Result<S::Ok, S::Error>
110where
111    T: IntoIterator,
112    T::Item: Serialize,
113    S: Serializer,
114{
115    let mut seq = serializer.serialize_seq()?;
116    for element in iter {
117        seq.serialize_element(&element)?;
118    }
119    seq.end()
120}
121
122impl<T: Serialize> Serialize for &[T] {
123    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
124        let mut seq = serializer.serialize_seq()?;
125        for item in self.iter() {
126            seq.serialize_element(item)?;
127        }
128
129        seq.end()
130    }
131}
132
133// Array
134impl<'de, const N: usize, T: Deserialize<'de>> Deserialize<'de> for [T; N] {
135    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
136        struct LimitFromIter<const N: usize, T, O> {
137            _marker: PhantomData<(T, O)>,
138            result: O,
139        }
140
141        impl<'de, const N: usize, T: Deserialize<'de>, O: FromIterator<T>> FromIterator<T>
142            for LimitFromIter<N, T, O>
143        {
144            fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
145                Self {
146                    _marker: PhantomData,
147                    result: O::from_iter(iter.into_iter().take(N)),
148                }
149            }
150        }
151
152        impl<'de, const N: usize, T: Deserialize<'de>, O: FromIterator<T>> Deserialize<'de>
153            for LimitFromIter<N, T, O>
154        {
155            fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
156                reader.deserialize_seq(IteratorVisitor::<_, Self>::default())
157            }
158        }
159
160        let vec = reader.deserialize_seq(IteratorVisitor::<
161            ValueOrWhitespace<T>,
162            NoWhitespaceIter<T, LimitFromIter<N, T, Vec<T>>>,
163        >::new())?;
164
165        vec.result
166            .result
167            .try_into()
168            .map_err(|_| de::Error::missing_data())
169    }
170}
171
172impl<const N: usize, T: Serialize> Serialize for [T; N] {
173    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
174        self.as_slice().serialize(serializer)
175    }
176}
177
178// Vec
179impl<'de, T: Deserialize<'de>> Deserialize<'de> for Vec<T> {
180    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
181        reader
182            .deserialize_seq(IteratorVisitor::<_, NoWhitespaceIter<_, Self>>::default())
183            .map(|a| a.result)
184    }
185}
186
187impl<T: Serialize> Serialize for Vec<T> {
188    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
189        self.as_slice().serialize(serializer)
190    }
191}
192
193// VecDeque
194impl<'de, T: Deserialize<'de>> Deserialize<'de> for VecDeque<T> {
195    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
196        reader
197            .deserialize_seq(IteratorVisitor::<_, NoWhitespaceIter<_, Self>>::default())
198            .map(|a| a.result)
199    }
200}
201
202impl<T: Serialize> Serialize for VecDeque<T> {
203    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
204        self.as_slices().0.serialize(serializer)
205    }
206}
207
208// LinkedList
209impl<'de, T: Deserialize<'de>> Deserialize<'de> for LinkedList<T> {
210    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
211        reader
212            .deserialize_seq(IteratorVisitor::<_, NoWhitespaceIter<_, Self>>::default())
213            .map(|a| a.result)
214    }
215}
216
217impl<T: Serialize> Serialize for LinkedList<T> {
218    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
219        serialize_seq(self.iter(), serializer)
220    }
221}
222
223// HashSet
224impl<'de, T: Deserialize<'de> + Eq + std::hash::Hash> Deserialize<'de> for HashSet<T> {
225    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
226        reader
227            .deserialize_seq(IteratorVisitor::<_, NoWhitespaceIter<_, Self>>::default())
228            .map(|a| a.result)
229    }
230}
231
232impl<T: Serialize> Serialize for HashSet<T> {
233    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
234        serialize_seq(self.iter(), serializer)
235    }
236}
237
238// BTreeSet
239impl<'de, T: Deserialize<'de> + Ord> Deserialize<'de> for BTreeSet<T> {
240    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
241        reader
242            .deserialize_seq(IteratorVisitor::<_, NoWhitespaceIter<_, Self>>::default())
243            .map(|a| a.result)
244    }
245}
246
247impl<T: Serialize> Serialize for BTreeSet<T> {
248    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
249        serialize_seq(self.iter(), serializer)
250    }
251}
252
253// HashMap
254impl<'de, K: Deserialize<'de> + Eq + std::hash::Hash, V: Deserialize<'de>> Deserialize<'de>
255    for HashMap<K, V>
256{
257    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
258        reader
259            .deserialize_seq(IteratorVisitor::<_, NoWhitespaceIter<_, Self>>::default())
260            .map(|a| a.result)
261    }
262}
263
264impl<K: Serialize, V: Serialize> Serialize for HashMap<K, V> {
265    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
266        serialize_seq(self.iter(), serializer)
267    }
268}