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
12/// This visitor allows for deserializing an iterator of elements, which can be useful for deserializing sequences of elements into a collection/single value.
13pub struct IteratorVisitor<T, V: FromIterator<T>> {
14    _marker: PhantomData<(T, V)>,
15}
16
17impl<T, V: FromIterator<T>> IteratorVisitor<T, V> {
18    /// Creates a new [`IteratorVisitor`].
19    pub fn new() -> Self {
20        Self {
21            _marker: PhantomData,
22        }
23    }
24}
25
26impl<T, V: FromIterator<T>> Default for IteratorVisitor<T, V> {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl<'de, T, V> Visitor<'de> for IteratorVisitor<T, V>
33where
34    T: Deserialize<'de>,
35    V: FromIterator<T> + Deserialize<'de>,
36{
37    type Value = V;
38
39    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
40        write!(formatter, "a sequence of elements")
41    }
42
43    fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
44    where
45        S: SeqAccess<'de>,
46    {
47        Ok(std::iter::from_fn(|| seq.next_element_seq::<T>().ok().flatten()).collect::<V>())
48    }
49}
50
51fn serialize_seq<T, S>(iter: T, serializer: S) -> Result<S::Ok, S::Error>
52where
53    T: IntoIterator,
54    T::Item: Serialize,
55    S: Serializer,
56{
57    let mut seq = serializer.serialize_seq()?;
58    for element in iter {
59        seq.serialize_element(&element)?;
60    }
61    seq.end()
62}
63
64/// This visitor allows for deserializing an iterator of elements up to a certain limit, which can be useful for deserializing sequences of elements into an array/fixed-size list.
65///
66/// For now, this visitor is pub(crate) because it's yet to be decided whether it could be replaced by a more general solution.
67pub(crate) struct LimitIteratorVisitor<T, V: FromIterator<T>> {
68    _marker: PhantomData<(T, V)>,
69    limit: usize,
70}
71
72impl<T, V: FromIterator<T>> LimitIteratorVisitor<T, V> {
73    /// Creates a new [`IteratorVisitor`].
74    pub fn new(limit: usize) -> Self {
75        Self {
76            _marker: PhantomData,
77            limit,
78        }
79    }
80}
81
82impl<'de, T, V> Visitor<'de> for LimitIteratorVisitor<T, V>
83where
84    T: Deserialize<'de>,
85    V: FromIterator<T> + Deserialize<'de>,
86{
87    type Value = V;
88
89    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
90        write!(formatter, "a sequence of elements")
91    }
92
93    fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
94    where
95        S: SeqAccess<'de>,
96    {
97        Ok(
98            std::iter::from_fn(|| seq.next_element_seq::<T>().ok().flatten())
99                .take(self.limit)
100                .collect::<V>(),
101        )
102    }
103}
104
105impl<T: Serialize> Serialize for &[T] {
106    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
107        let mut seq = serializer.serialize_seq()?;
108        for item in self.iter() {
109            seq.serialize_element(item)?;
110        }
111
112        seq.end()
113    }
114}
115
116// Array
117impl<'de, const N: usize, T: Deserialize<'de>> Deserialize<'de> for [T; N] {
118    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
119        let vec: Vec<T> = reader.deserialize_seq(LimitIteratorVisitor::new(N))?;
120
121        vec.try_into().map_err(|_| de::Error::missing_data())
122    }
123}
124
125impl<const N: usize, T: Serialize> Serialize for [T; N] {
126    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
127        self.as_slice().serialize(serializer)
128    }
129}
130
131// Vec
132impl<'de, T: Deserialize<'de>> Deserialize<'de> for Vec<T> {
133    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
134        reader.deserialize_seq(IteratorVisitor::new())
135    }
136}
137
138impl<T: Serialize> Serialize for Vec<T> {
139    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
140        self.as_slice().serialize(serializer)
141    }
142}
143
144// VecDeque
145impl<'de, T: Deserialize<'de>> Deserialize<'de> for VecDeque<T> {
146    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
147        reader.deserialize_seq(IteratorVisitor::new())
148    }
149}
150
151impl<T: Serialize> Serialize for VecDeque<T> {
152    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
153        self.as_slices().0.serialize(serializer)
154    }
155}
156
157// LinkedList
158impl<'de, T: Deserialize<'de>> Deserialize<'de> for LinkedList<T> {
159    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
160        reader.deserialize_seq(IteratorVisitor::new())
161    }
162}
163
164impl<T: Serialize> Serialize for LinkedList<T> {
165    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
166        self.iter().collect::<Vec<_>>().serialize(serializer)
167    }
168}
169
170// HashSet
171impl<'de, T: Deserialize<'de> + Eq + std::hash::Hash> Deserialize<'de> for HashSet<T> {
172    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
173        reader.deserialize_seq(IteratorVisitor::new())
174    }
175}
176
177impl<T: Serialize> Serialize for HashSet<T> {
178    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
179        self.iter().collect::<Vec<_>>().serialize(serializer)
180    }
181}
182
183// BTreeSet
184impl<'de, T: Deserialize<'de> + Ord> Deserialize<'de> for BTreeSet<T> {
185    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
186        reader.deserialize_seq(IteratorVisitor::new())
187    }
188}
189
190impl<T: Serialize> Serialize for BTreeSet<T> {
191    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
192        self.iter().collect::<Vec<_>>().serialize(serializer)
193    }
194}
195
196// HashMap
197impl<'de, K: Deserialize<'de> + Eq + std::hash::Hash, V: Deserialize<'de>> Deserialize<'de>
198    for HashMap<K, V>
199{
200    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
201        reader.deserialize_seq(IteratorVisitor::<(K, V), _>::new())
202    }
203}
204
205impl<K: Serialize, V: Serialize> Serialize for HashMap<K, V> {
206    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
207        serialize_seq(self.iter(), serializer)
208    }
209}