serde_tagged/de/
seed.rs

1//! `DeserializeSeed` implementations for tagged value deserialization and creation thereof.
2
3use std;
4use std::collections::{BTreeMap, HashMap};
5use std::marker::PhantomData;
6
7use util::TagString;
8
9use serde;
10
11
12/// A factory that creates a `DeserializeSeed` implementation based on a given
13/// tag.
14///
15/// Convenience implementations of this trait are provided for the standard map
16/// types with `&'static str` and `String` as key, as well as
17/// [`WithoutTag`](WithoutTag) and [`WithTag`](WithTag).
18pub trait SeedFactory<'de, T> {
19    /// The type of the value that will be produced by the `DeserializeSeed`
20    /// implementation.
21    type Value;
22
23    /// The type of the `DeserializeSeed` implementation that will be returned
24    /// by this factory.
25    type Seed: serde::de::DeserializeSeed<'de, Value = Self::Value>;
26
27    /// Returns the seed that should be used to deserialize a value tagged with
28    /// the given tag.
29    fn seed<E>(self, tag: T) -> Result<Self::Seed, E>
30    where
31        E: serde::de::Error;
32}
33
34
35impl<'de, T, V> SeedFactory<'de, T> for PhantomData<V>
36where
37    V: serde::Deserialize<'de>,
38{
39    type Value = V;
40    type Seed = PhantomData<V>;
41
42    fn seed<E>(self, _tag: T) -> Result<Self::Seed, E>
43    where
44        E: serde::de::Error,
45    {
46        Ok(PhantomData)
47    }
48}
49
50
51/// A [`SeedFactory`](SeedFactory) implementation that can be used to discard
52/// the tag during deserialization.
53///
54/// This implementation creates a seed which deserializes a tagged value with
55/// known type and discards the tag.
56///
57/// This is equivalent to the [`SeedFactory`](SeedFactory) implementation
58/// provided for `PhantomData` and has been added for consistency and
59/// clarification.
60pub struct WithoutTag<V> {
61    _phantom: PhantomData<V>,
62}
63
64impl<V> WithoutTag<V> {
65    /// Creates a new [`SeedFactory`](SeedFactory) implementation that
66    /// deserializes a tagged value with known type and discards its tag.
67    pub fn new() -> Self {
68        WithoutTag {
69            _phantom: PhantomData,
70        }
71    }
72}
73
74impl<V> Default for WithoutTag<V> {
75    fn default() -> Self {
76        WithoutTag::new()
77    }
78}
79
80impl<'de, T, V> SeedFactory<'de, T> for WithoutTag<V>
81where
82    V: serde::Deserialize<'de>,
83{
84    type Value = V;
85    type Seed = PhantomData<V>;
86
87    fn seed<E>(self, _tag: T) -> Result<Self::Seed, E>
88    where
89        E: serde::de::Error,
90    {
91        Ok(PhantomData)
92    }
93}
94
95/// A [`SeedFactory`](SeedFactory) implementation that can be used to retreive
96/// a tag and value of known type.
97///
98/// This implementation creates a seed which deserializes a tagged value with
99/// known type and returns a tuple containing tag and value.
100pub struct WithTag<V> {
101    _phantom: PhantomData<V>,
102}
103
104impl<V> WithTag<V> {
105    /// Creates a new [`SeedFactory`](SeedFactory) implementation that
106    /// deserializes a tagged value with known type and returns both tag and
107    /// value as tuple.
108    pub fn new() -> Self {
109        WithTag {
110            _phantom: PhantomData,
111        }
112    }
113}
114
115impl<V> Default for WithTag<V> {
116    fn default() -> Self {
117        WithTag::new()
118    }
119}
120
121impl<'de, V, T> SeedFactory<'de, T> for WithTag<V>
122where
123    V: serde::Deserialize<'de>,
124{
125    type Value = (T, V);
126    type Seed = DeserializeWithTag<T, V>;
127
128    fn seed<E>(self, tag: T) -> Result<Self::Seed, E>
129    where
130        E: serde::de::Error,
131    {
132        Ok(DeserializeWithTag::new(tag))
133    }
134}
135
136
137/// A `DeserializeSeed` implementation that returns the pair of wrapped tag and
138/// deserialized value of known type.
139pub struct DeserializeWithTag<T, V> {
140    tag:      T,
141    _phantom: PhantomData<V>,
142}
143
144impl<T, V> DeserializeWithTag<T, V> {
145    /// Creates a new `DeserializeSeed` implementation that returns the pair of
146    /// given tag and deserialized value.
147    pub fn new(tag: T) -> Self {
148        DeserializeWithTag {
149            tag,
150            _phantom: PhantomData,
151        }
152    }
153}
154
155impl<'de, T, V> serde::de::DeserializeSeed<'de> for DeserializeWithTag<T, V>
156where
157    V: serde::Deserialize<'de>,
158{
159    type Value = (T, V);
160
161    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
162    where
163        D: serde::Deserializer<'de>,
164    {
165        Ok((self.tag, V::deserialize(deserializer)?))
166    }
167}
168
169
170impl<'de, V, S> SeedFactory<'de, TagString<'de>> for BTreeMap<&'static str, S>
171where
172    S: serde::de::DeserializeSeed<'de, Value = V>,
173{
174    type Value = V;
175    type Seed = S;
176
177    fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
178    where
179        E: serde::de::Error,
180    {
181        self.remove(tag.as_ref())
182            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
183    }
184}
185
186impl<'de, V, S, H> SeedFactory<'de, TagString<'de>> for HashMap<&'static str, S, H>
187where
188    S: serde::de::DeserializeSeed<'de, Value = V>,
189    H: std::hash::BuildHasher,
190{
191    type Value = V;
192    type Seed = S;
193
194    fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
195    where
196        E: serde::de::Error,
197    {
198        self.remove(tag.as_ref())
199            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
200    }
201}
202
203
204impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r mut BTreeMap<&'static str, S>
205where
206    &'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
207{
208    type Value = V;
209    type Seed = &'r mut S;
210
211    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
212    where
213        E: serde::de::Error,
214    {
215        self.get_mut(tag.as_ref())
216            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
217    }
218}
219
220impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r mut HashMap<&'static str, S, H>
221where
222    &'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
223    H: std::hash::BuildHasher,
224{
225    type Value = V;
226    type Seed = &'r mut S;
227
228    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
229    where
230        E: serde::de::Error,
231    {
232        self.get_mut(tag.as_ref())
233            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
234    }
235}
236
237
238impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r BTreeMap<&'static str, S>
239where
240    &'r S: serde::de::DeserializeSeed<'de, Value = V>,
241{
242    type Value = V;
243    type Seed = &'r S;
244
245    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
246    where
247        E: serde::de::Error,
248    {
249        self.get(tag.as_ref())
250            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
251    }
252}
253
254impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r HashMap<&'static str, S, H>
255where
256    &'r S: serde::de::DeserializeSeed<'de, Value = V>,
257    H: std::hash::BuildHasher,
258{
259    type Value = V;
260    type Seed = &'r S;
261
262    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
263    where
264        E: serde::de::Error,
265    {
266        self.get(tag.as_ref())
267            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
268    }
269}
270
271
272impl<'de, V, S> SeedFactory<'de, TagString<'de>> for BTreeMap<String, S>
273where
274    S: serde::de::DeserializeSeed<'de, Value = V>,
275{
276    type Value = V;
277    type Seed = S;
278
279    fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
280    where
281        E: serde::de::Error,
282    {
283        self.remove(tag.as_ref())
284            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
285    }
286}
287
288impl<'de, V, S, H> SeedFactory<'de, TagString<'de>> for HashMap<String, S, H>
289where
290    S: serde::de::DeserializeSeed<'de, Value = V>,
291    H: std::hash::BuildHasher,
292{
293    type Value = V;
294    type Seed = S;
295
296    fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
297    where
298        E: serde::de::Error,
299    {
300        self.remove(tag.as_ref())
301            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
302    }
303}
304
305
306impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r mut BTreeMap<String, S>
307where
308    &'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
309{
310    type Value = V;
311    type Seed = &'r mut S;
312
313    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
314    where
315        E: serde::de::Error,
316    {
317        self.get_mut(tag.as_ref())
318            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
319    }
320}
321
322impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r mut HashMap<String, S, H>
323where
324    &'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
325    H: std::hash::BuildHasher,
326{
327    type Value = V;
328    type Seed = &'r mut S;
329
330    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
331    where
332        E: serde::de::Error,
333    {
334        self.get_mut(tag.as_ref())
335            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
336    }
337}
338
339
340impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r BTreeMap<String, S>
341where
342    &'r S: serde::de::DeserializeSeed<'de, Value = V>,
343{
344    type Value = V;
345    type Seed = &'r S;
346
347    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
348    where
349        E: serde::de::Error,
350    {
351        self.get(tag.as_ref())
352            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
353    }
354}
355
356impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r HashMap<String, S, H>
357where
358    &'r S: serde::de::DeserializeSeed<'de, Value = V>,
359    H: std::hash::BuildHasher,
360{
361    type Value = V;
362    type Seed = &'r S;
363
364    fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
365    where
366        E: serde::de::Error,
367    {
368        self.get(tag.as_ref())
369            .ok_or_else(|| serde::de::Error::custom("Unknown tag"))
370    }
371}
372
373
374#[cfg(feature = "erased")]
375mod erased {
376    //! Utilities for trait-objects.
377
378    use erased_serde;
379    use serde;
380
381
382    /// A trait alias for mutable closures that can be used as
383    /// `DeserializeSeed` in combination with `BoxFnMutSeed`.
384    pub trait FnMutSeed<V>
385        : for<'de> FnMut(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>
386    {}
387
388    impl<V, F> FnMutSeed<V> for F
389    where
390        F: for<'de> FnMut(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>,
391    {}
392
393
394    /// A boxed mutable closure that can be used as `DeserializeSeed`.
395    ///
396    /// It additionally requires the wrapped closure to implement `Sync` which
397    /// allows for easy static type-registry creation, e.g. in combination with
398    /// `BTreeMap<&'static str, _>`.
399    pub struct BoxFnMutSeed<V>(Box<dyn FnMutSeed<V, Output = Result<V, erased_serde::Error>> + Sync>);
400
401    impl<V> BoxFnMutSeed<V> {
402        /// Creates a new boxed closure from the given closure.
403        pub fn new<F>(func: F) -> Self
404        where
405            F: FnMutSeed<V> + Sync + 'static,
406        {
407            BoxFnMutSeed(Box::new(func))
408        }
409    }
410
411    impl<'de, V> serde::de::DeserializeSeed<'de> for BoxFnMutSeed<V> {
412        type Value = V;
413
414        fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error>
415        where
416            D: serde::Deserializer<'de>,
417        {
418            let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
419            (self.0)(&mut de).map_err(serde::de::Error::custom)
420        }
421    }
422
423    impl<'de, 'b, V> serde::de::DeserializeSeed<'de> for &'b mut BoxFnMutSeed<V> {
424        type Value = V;
425
426        fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
427        where
428            D: serde::Deserializer<'de>,
429        {
430            let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
431            (self.0)(&mut de).map_err(serde::de::Error::custom)
432        }
433    }
434
435
436    /// A trait alias for (immutable) closures that can be used as
437    /// `DeserializeSeed` in combination with `BoxFnSeed`.
438    pub trait FnSeed<V>
439        : for<'de> Fn(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>
440    {}
441
442    impl<V, F> FnSeed<V> for F
443    where
444        F: for<'de> Fn(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>,
445    {}
446
447
448    /// A boxed (immutable) closure that can be used as `DeserializeSeed`.
449    ///
450    /// It additionally requires the wrapped closure to implement `Sync` which
451    /// allows for easy static type-registry creation, e.g. in combination with
452    /// `BTreeMap<&'static str, _>`.
453    pub struct BoxFnSeed<V>(Box<dyn FnSeed<V, Output = Result<V, erased_serde::Error>> + Sync>);
454
455    impl<V> BoxFnSeed<V> {
456        /// Creates a new boxed closure from the given closure.
457        pub fn new<F>(func: F) -> Self
458        where
459            F: FnSeed<V> + Sync + 'static,
460        {
461            BoxFnSeed(Box::new(func))
462        }
463    }
464
465    impl<'de, V> serde::de::DeserializeSeed<'de> for BoxFnSeed<V> {
466        type Value = V;
467
468        fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
469        where
470            D: serde::Deserializer<'de>,
471        {
472            let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
473            (self.0)(&mut de).map_err(serde::de::Error::custom)
474        }
475    }
476
477    impl<'de, 'b, V> serde::de::DeserializeSeed<'de> for &'b BoxFnSeed<V> {
478        type Value = V;
479
480        fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
481        where
482            D: serde::Deserializer<'de>,
483        {
484            let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
485            (self.0)(&mut de).map_err(serde::de::Error::custom)
486        }
487    }
488}
489
490#[cfg(feature = "erased")]
491pub use self::erased::{BoxFnMutSeed, BoxFnSeed, FnMutSeed, FnSeed};