Skip to main content

feanor_serde/
seq.rs

1use std::marker::PhantomData;
2
3use serde::de::{DeserializeSeed, Error, SeqAccess, Visitor};
4use serde::ser::{Serialize, SerializeSeq, Serializer};
5
6///
7/// Wraps an [`Iterator`] over serializable elements, and implements
8/// [`Serialize`] by mapping the sequence of elements to the seq type
9/// in the serde data model.
10/// 
11pub struct SerializableSeq<I>
12    where I: Iterator + Clone
13{
14    data: I,
15    len: Option<usize>
16}
17
18impl<I> SerializableSeq<I>
19    where I: Iterator + Clone
20{
21    pub fn new(data: I) -> Self {
22        Self { data: data, len: None }
23    }
24
25    pub fn new_with_len(data: I, len: usize) -> Self {
26        assert!(data.size_hint().0 <= len);
27        assert!(data.size_hint().1.is_none() || data.size_hint().1.unwrap() >= len);
28        Self { data: data, len: Some(len) }
29    }
30}
31
32impl<I> Serialize for SerializableSeq<I>
33    where I: Iterator + Clone, 
34        I::Item: Serialize
35{
36    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
37        where S: Serializer
38    {
39        let mut seq = serializer.serialize_seq(self.len)?;
40        for x in self.data.clone() {
41            seq.serialize_element(&x)?;
42        }
43        return seq.end();
44    }
45}
46
47///
48/// A [`DeserializeSeed`] that deserializes a sequence by deserializing each
49/// element with a given [`DeserializeSeed`], and combining the result with a
50/// given combinator.
51/// 
52/// # Length of the seed sequence
53/// 
54/// The iterator producing the seeds must contain at least one more seed than the
55/// sequence to deserialize has elements. The reason is that for generic deserializers,
56/// we don't know whether we reached the end unless we try to deserialize an element
57/// beyond the end. However, to do that, we need a seed.
58/// 
59/// # Example
60/// ```
61/// # use feanor_serde::seq::*;
62/// # use std::marker::PhantomData;
63/// # use std::iter::repeat;
64/// # use serde::de::DeserializeSeed;
65/// let mut deserializer = serde_json::Deserializer::new(serde_json::de::StrRead::new("[1, 3, 5]"));
66/// let deserialize_seed = DeserializeSeedSeq::new(
67///     repeat(PhantomData::<i64>),
68///     Vec::new(),
69///     |mut current, next| { current.push(next); current }
70/// );
71/// assert_eq!(vec![1, 3, 5], deserialize_seed.deserialize(&mut deserializer).unwrap());
72/// ```
73/// 
74pub struct DeserializeSeedSeq<'de, V, S, T, C>
75    where V: Iterator<Item = S>,
76        S: DeserializeSeed<'de>,
77        C: FnMut(T, S::Value) -> T
78{
79    deserializer: PhantomData<&'de ()>,
80    element_seed: PhantomData<S>,
81    seeds: V,
82    initial: T,
83    collector: C
84}
85
86impl<'de, V, S, T, C> DeserializeSeedSeq<'de, V, S, T, C>
87    where V: Iterator<Item = S>,
88        S: DeserializeSeed<'de>,
89        C: FnMut(T, S::Value) -> T
90{
91    pub fn new(seeds: V, initial: T, collector: C) -> Self {
92        Self {
93            deserializer: PhantomData,
94            element_seed: PhantomData,
95            seeds: seeds,
96            initial: initial,
97            collector: collector
98        }
99    }
100}
101
102impl<'de, V, S, T, C> DeserializeSeed<'de> for DeserializeSeedSeq<'de, V, S, T, C>
103    where V: Iterator<Item = S>, 
104        S: DeserializeSeed<'de>,
105        C: FnMut(T, S::Value) -> T
106{
107    type Value = T;
108
109    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
110        where D: serde::Deserializer<'de>
111    {
112        struct ResultVisitor<'de, V, S, T, C>
113            where V: Iterator<Item = S>,
114                S: DeserializeSeed<'de>,
115                C: FnMut(T, S::Value) -> T
116        {
117            deserializer: PhantomData<&'de ()>,
118            element_seed: PhantomData<S>,
119            seeds: V,
120            initial: T,
121            collector: C
122        }
123
124        impl<'de, V, S, T, C> Visitor<'de> for ResultVisitor<'de, V, S, T, C>
125            where V: Iterator<Item = S>,
126                S: DeserializeSeed<'de>,
127                C: FnMut(T, S::Value) -> T
128        {
129            type Value = T;
130
131            fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
132                write!(f, "a sequence of elements")
133            }
134
135            fn visit_seq<B>(mut self, mut seq: B) -> Result<Self::Value, B::Error>
136                where B: SeqAccess<'de>
137            {
138                let mut result = self.initial;
139                let mut current_len = 0;
140                while let Some(seed) = self.seeds.next() {
141                    let el = seq.next_element_seed(seed)?;
142                    if let Some(el) = el {
143                        current_len += 1;
144                        result = (self.collector)(result, el);
145                    } else {
146                        return Ok(result);
147                    }
148                }
149                return Err(Error::invalid_length(current_len, &format!("a sequence of length at most {}", current_len - 1).as_str()))
150            }
151        }
152
153        return deserializer.deserialize_seq(ResultVisitor {
154            deserializer: PhantomData,
155            element_seed: PhantomData,
156            collector: self.collector,
157            initial: self.initial,
158            seeds: self.seeds
159        });
160    }
161}
162
163#[cfg(test)]
164use std::iter::{repeat, repeat_with};
165
166#[cfg(test)]
167fn testdata() -> Vec<Vec<i64>> {
168    vec![
169        Vec::new(),
170        vec![1, 3],
171        vec![1, 3, 4]
172    ]
173}
174
175#[test]
176fn test_serde_postcard() {
177    for data in testdata() {
178        let serialized = postcard::to_allocvec(&SerializableSeq::new_with_len(data.iter().copied(), data.len())).unwrap();
179        let result = DeserializeSeedSeq::new(repeat(PhantomData::<i64>), Vec::new(), |mut current, next| { current.push(next); current }).deserialize(
180            &mut postcard::Deserializer::from_flavor(postcard::de_flavors::Slice::new(&serialized))
181        ).unwrap();
182        assert_eq!(data, result);
183    }
184}
185
186#[test]
187fn test_serde_json() {
188    for data in testdata() {
189        let serialized = serde_json::to_string(&SerializableSeq::new(data.iter().copied())).unwrap();
190        let result = DeserializeSeedSeq::new(repeat(PhantomData::<i64>), Vec::new(), |mut current, next| { current.push(next); current }).deserialize(
191            &mut serde_json::Deserializer::from_str(&serialized)
192        ).unwrap();
193        assert_eq!(data, result);
194        
195        let serialized = serde_json::to_string(&SerializableSeq::new_with_len(data.iter().copied(), data.len())).unwrap();
196        let result = DeserializeSeedSeq::new(repeat(PhantomData::<i64>), Vec::new(), |mut current, next| { current.push(next); current }).deserialize(
197            &mut serde_json::Deserializer::from_str(&serialized)
198        ).unwrap();
199        assert_eq!(data, result);
200    }
201}
202
203#[test]
204fn test_deserialize_sequence_partially_json() {
205    let data = vec![vec![1, 2, 3, 4], vec![1, 2, 3]];
206    let serialized = serde_json::to_string(&SerializableSeq::new(data.iter().map(|data| SerializableSeq::new(data.iter())))).unwrap();
207    let result = DeserializeSeedSeq::new(repeat_with(|| DeserializeSeedSeq::new(
208            (0..5).map(|_| PhantomData::<i64>),
209            Vec::new(),
210            |mut current, next|  { current.push(next); current }
211        )), 
212        Vec::new(), 
213        |mut current, next| { current.push(next); current }
214    ).deserialize(
215        &mut serde_json::Deserializer::from_str(&serialized)
216    ).unwrap();
217    assert_eq!(data, result);
218}
219
220#[test]
221fn test_deserialize_sequence_partially_postcard() {
222    let data = vec![vec![1, 2, 3, 4], vec![1, 2, 3]];
223    let serialized = postcard::to_allocvec(&SerializableSeq::new_with_len(data.iter().map(|data| SerializableSeq::new_with_len(data.iter(), data.len())), data.len())).unwrap();
224    let result = DeserializeSeedSeq::new(repeat_with(|| DeserializeSeedSeq::new(
225            (0..5).map(|_| PhantomData::<i64>),
226            Vec::new(),
227            |mut current, next|  { current.push(next); current }
228        )), 
229        Vec::new(), 
230        |mut current, next| { current.push(next); current }
231    ).deserialize(
232        &mut postcard::Deserializer::from_flavor(postcard::de_flavors::Slice::new(&serialized))
233    ).unwrap();
234    assert_eq!(data, result);
235}