serde_tagged/de/adj/
tuple.rs

1//! Deserialization of adjacently tagged values using tuples.
2//!
3//! See [`ser::adj::tuple`](::ser::adj::tuple) for a description of this tagging
4//! format.
5
6use de::seed::SeedFactory;
7
8use std::fmt;
9use std::marker::PhantomData;
10
11use serde;
12
13
14/// Deserialize a tuple-based adjacently tagged value.
15///
16/// The deserializer controls the underlying data format while the seed-factory
17/// specifies the instructions (depending on the tag) on how the value should be
18/// deserialized.
19///
20/// See [`de`](::de) for more information on
21/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
22///
23/// See [`deserialize_seed`](deserialize_seed) for a version that allows you to
24/// pass a `DeserializeSeed` implementation to deserialize the tag. This version
25/// is equivalent to `deserialize_seed(deserializer, seed_factory,
26/// PhantomData<T>)`
27pub fn deserialize<'de, T, D, F>(deserializer: D, seed_factory: F) -> Result<F::Value, D::Error>
28where
29    T: serde::Deserialize<'de>,
30    D: serde::Deserializer<'de>,
31    F: SeedFactory<'de, T>,
32{
33    deserialize_seed(deserializer, seed_factory, PhantomData::<T>)
34}
35
36
37/// Deserialize a tuple-based adjacently tagged value with the given tag-seed.
38///
39/// The deserializer controls the underlying data format while the seed-factory
40/// specifies the instructions (depending on the tag) on how the value should be
41/// deserialized.
42///
43/// See [`de`](::de) for more information on
44/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
45pub fn deserialize_seed<'de, D, F, S>(
46    deserializer: D,
47    seed_factory: F,
48    tag_seed: S,
49) -> Result<F::Value, D::Error>
50where
51    D: serde::Deserializer<'de>,
52    F: SeedFactory<'de, S::Value>,
53    S: serde::de::DeserializeSeed<'de>,
54{
55    deserializer.deserialize_tuple(2, Visitor::new(seed_factory, tag_seed))
56}
57
58
59/// A visitor that can be used to deserialize a tuple-based adjacently tagged
60/// value.
61///
62/// This visitor handles a tuple-based adjacently tagged value, which is
63/// represented by a tuple containing exactly two elements. The first element of
64/// this tuple is the tag, the second element the value. Thus this visitor will
65/// return an error if the visited type is not a tuple (i.e. sequence) with two
66/// elements.
67///
68/// The [`SeedFactory`](::de::SeedFactory) provided to this visitor
69/// provides a `serde::de::DeserializeSeed` implementation depending on the tag,
70/// which then determines how the value is going to be deserialized.
71///
72/// See [`de`](::de) for more information on
73/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
74pub struct Visitor<F, S> {
75    seed_factory: F,
76    tag_seed:     S,
77}
78
79impl<F, S> Visitor<F, S> {
80    /// Creates a new visitor with the given
81    /// [`SeedFactory`](::de::SeedFactory).
82    pub fn new(seed_factory: F, tag_seed: S) -> Self {
83        Visitor {
84            seed_factory,
85            tag_seed,
86        }
87    }
88}
89
90impl<'de, F, S> serde::de::Visitor<'de> for Visitor<F, S>
91where
92    F: SeedFactory<'de, S::Value>,
93    S: serde::de::DeserializeSeed<'de>,
94{
95    type Value = F::Value;
96
97    fn expecting(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
98        write!(fmtr, "a tuple with exactly two elements")
99    }
100
101    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
102    where
103        A: serde::de::SeqAccess<'de>,
104    {
105        use serde::de::Error;
106
107        // try to validate the length
108        match seq.size_hint() {
109            Some(n) if n != 2 => Err(Error::invalid_length(n, &self))?,
110            _ => {},
111        }
112
113        let tag = seq.next_element_seed(self.tag_seed)?
114            .ok_or_else(|| Error::invalid_length(0, &"a tuple with exactly two elements"))?;
115
116        seq.next_element_seed(self.seed_factory.seed(tag)?)?
117            .ok_or_else(|| Error::invalid_length(1, &"a tuple with exactly two elements"))
118    }
119}