serde_tagged/de/adj/
struc.rs

1//! Deserialization of adjacently tagged values using structs.
2//!
3//! See [`ser::adj::struc`](::ser::adj::struc) for a description of this tagging
4//! format.
5//!
6//! # Warning
7//!
8//! If the deserialization-process depends on the tag (i.e. with
9//! [`deserialize`](deserialize) and/or [`Visitor`](Visitor)),
10//! deserialization of struct-based adjacently tagged values is only supported
11//! for self-describing formats.
12
13use de::seed::SeedFactory;
14use util::de::content::{Content, ContentDeserializer};
15
16use std;
17use std::marker::PhantomData;
18
19use serde;
20
21
22/// Deserialize a struct-based adjacently tagged value.
23///
24/// The deserializer controls the underlying data format while the seed-factory
25/// specifies the instructions (depending on the tag) on how the value should be
26/// deserialized.
27///
28/// `name` is the name with which the struct that will be serialized.
29///
30/// See [`de`](::de) for more information on
31/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
32///
33/// See [`deserialize_seed`](deserialize_seed) for a version that allows you to
34/// pass a `DeserializeSeed` implementation to deserialize the tag. This version
35/// is equivalent to `deserialize_seed(deserializer, seed_factory,
36/// PhantomData<T>)`
37///
38/// # Note
39///
40/// If you do not need to choose a specific deserialization-method based on the
41/// tag, you should prefer [`deserialize_known`](deserialize_known) to this
42/// method.
43pub fn deserialize<'de, T, D, F>(
44    deserializer: D,
45    name: &'static str,
46    tag_key: &'static str,
47    value_key: &'static str,
48    seed_factory: F,
49) -> Result<F::Value, D::Error>
50where
51    T: serde::Deserialize<'de>,
52    D: serde::Deserializer<'de>,
53    F: SeedFactory<'de, T>,
54{
55    deserialize_seed(
56        deserializer,
57        name,
58        tag_key,
59        value_key,
60        seed_factory,
61        PhantomData::<T>,
62    )
63}
64
65
66/// Deserialize a struct-based adjacently tagged value using the given tag-seed.
67///
68/// The deserializer controls the underlying data format while the seed-factory
69/// specifies the instructions (depending on the tag) on how the value should be
70/// deserialized.
71///
72/// `name` is the name with which the struct that will be serialized.
73///
74/// See [`de`](::de) for more information on
75/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
76///
77/// # Note
78///
79/// If you do not need to choose a specific deserialization-method based on the
80/// tag, you should prefer [`deserialize_known_seed`](deserialize_known_seed) to
81/// this method.
82pub fn deserialize_seed<'de, D, F, S>(
83    deserializer: D,
84    name: &'static str,
85    tag_key: &'static str,
86    value_key: &'static str,
87    seed_factory: F,
88    tag_seed: S,
89) -> Result<F::Value, D::Error>
90where
91    D: serde::Deserializer<'de>,
92    F: SeedFactory<'de, S::Value>,
93    S: serde::de::DeserializeSeed<'de>,
94{
95    deserializer.deserialize_struct(
96        name,
97        &["tag-key", "value-key"],
98        Visitor::new(tag_key, value_key, seed_factory, tag_seed),
99    )
100}
101
102
103/// A visitor that can be used to deserialize a struct-based adjacently tagged
104/// value.
105///
106/// This visitor handles a struct-based adjacently tagged value, which is
107/// represented by a struct containing exactly two fields. The first field of
108/// this tuple is named according to tag-key and contains tag, the second field
109/// is named according to value-key and contains the value. Thus this visitor
110/// will return an error if the visited type is not a map or sequence with two
111/// entries.
112///
113/// `name` is the name with which the struct that will be serialized.
114///
115/// The [`SeedFactory`](::de::SeedFactory) provided to this visitor
116/// provides a `serde::de::DeserializeSeed` implementation depending on the tag,
117/// which then determines how the value is going to be deserialized.
118///
119/// See [`de`](::de) for more information on
120/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
121///
122/// # Note
123///
124/// If you do not need to choose a specific deserialization-method based on the
125/// tag, you should prefer [`KnownVisitor`](KnownVisitor) to this visitor.
126pub struct Visitor<F, S> {
127    seed_factory: F,
128    tag_seed:     S,
129    tag_key:      &'static str,
130    value_key:    &'static str,
131}
132
133impl<F, S> Visitor<F, S> {
134    /// Creates a new visitor with the given
135    /// [`SeedFactory`](::de::SeedFactory), tag-key and value-key.
136    pub fn new(
137        tag_key: &'static str,
138        value_key: &'static str,
139        seed_factory: F,
140        tag_seed: S,
141    ) -> Self {
142        Visitor {
143            seed_factory,
144            tag_seed,
145            tag_key,
146            value_key,
147        }
148    }
149}
150
151impl<'de, F, S> serde::de::Visitor<'de> for Visitor<F, S>
152where
153    F: SeedFactory<'de, S::Value>,
154    S: serde::de::DeserializeSeed<'de>,
155{
156    type Value = F::Value;
157
158    fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
159        write!(fmt, "a struct with exactly two fields")
160    }
161
162    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
163    where
164        A: serde::de::MapAccess<'de>,
165    {
166        use serde::de::DeserializeSeed;
167        use serde::de::Error;
168
169        let key_1 = map.next_key_seed(KeySeed::new(self.tag_key, self.value_key))?
170            .ok_or_else(|| Error::invalid_length(0, &self))?;
171
172        match key_1 {
173            Key::Tag => {
174                let tag = map.next_value_seed(self.tag_seed)?;
175
176                let value_key = map.next_key_seed(KeySeed::new(self.tag_key, self.value_key))?
177                    .ok_or_else(|| Error::custom("missing value"))?;
178
179                if value_key == Key::Value {
180                    Ok(map.next_value_seed(self.seed_factory.seed(tag)?)?)
181                } else {
182                    Err(Error::duplicate_field(self.tag_key))
183                }
184            },
185            Key::Value => {
186                let value: Content = map.next_value()?;
187
188                let tag_key = map.next_key_seed(KeySeed::new(self.tag_key, self.value_key))?
189                    .ok_or_else(|| Error::missing_field(self.value_key))?;
190
191                let tag = if tag_key == Key::Tag {
192                    map.next_value_seed(self.tag_seed)
193                } else {
194                    Err(Error::custom(
195                        "invalid entry key, expected the specified tag-key",
196                    ))
197                }?;
198
199                let de = ContentDeserializer::new(value);
200                self.seed_factory.seed(tag)?.deserialize(de)
201            },
202        }
203    }
204
205    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
206    where
207        A: serde::de::SeqAccess<'de>,
208    {
209        use serde::de::Error;
210
211        let tag = seq.next_element_seed(self.tag_seed)?
212            .ok_or_else(|| Error::invalid_length(0, &"a struct with exactly two fields"))?;
213
214        let value = seq.next_element_seed(self.seed_factory.seed(tag)?)?
215            .ok_or_else(|| Error::invalid_length(1, &"a struct with exactly two fields"))?;
216
217        Ok(value)
218    }
219}
220
221
222/// Deserialize a struct-based adjacently tagged value of known type.
223///
224/// The deserializer controls the underlying data format while the seed-factory
225/// specifies the instructions (depending on the tag) on how the value should be
226/// deserialized.
227///
228/// `name` is the name with which the struct that will be serialized.
229///
230/// See [`de`](::de) for more information on
231/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
232///
233/// See [`deserialize_known_seed`](deserialize_known_seed) for a version that
234/// allows you to pass `DeserializeSeed` implementations to deserialize the tag
235/// and value. This version is equivalent to
236/// `deserialize_known_seed(deserializer, seed_factory, PhantomData<T>,
237/// PhantomData<V>)`
238///
239/// # Note
240///
241/// If you do not need to choose a specific deserialization-method based on the
242/// tag, you should prefer this method to [`deserialize`](deserialize).
243pub fn deserialize_known<'de, T, V, D>(
244    deserializer: D,
245    name: &'static str,
246    tag_key: &'static str,
247    value_key: &'static str,
248) -> Result<(T, V), D::Error>
249where
250    T: serde::Deserialize<'de>,
251    V: serde::Deserialize<'de>,
252    D: serde::Deserializer<'de>,
253{
254    deserialize_known_seed(
255        deserializer,
256        name,
257        tag_key,
258        value_key,
259        PhantomData::<T>,
260        PhantomData::<V>,
261    )
262}
263
264
265/// Deserialize a struct-based adjacently tagged value of known type with the given seeds.
266///
267/// The deserializer controls the underlying data format while the seed-factory
268/// specifies the instructions (depending on the tag) on how the value should be
269/// deserialized.
270///
271/// See [`de`](::de) for more information on
272/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
273///
274/// # Note
275///
276/// If you do not need to choose a specific deserialization-method based on the
277/// tag, you should prefer this method to
278/// [`deserialize_known`](deserialize_known).
279pub fn deserialize_known_seed<'de, T, V, D>(
280    deserializer: D,
281    name: &'static str,
282    tag_key: &'static str,
283    value_key: &'static str,
284    tag_seed: T,
285    value_seed: V,
286) -> Result<(T::Value, V::Value), D::Error>
287where
288    T: serde::de::DeserializeSeed<'de>,
289    V: serde::de::DeserializeSeed<'de>,
290    D: serde::Deserializer<'de>,
291{
292    deserializer.deserialize_struct(
293        name,
294        &["tag-key", "value-key"],
295        KnownVisitor::<T, V>::new(tag_seed, value_seed, tag_key, value_key),
296    )
297}
298
299
300/// A visitor that can be used to deserialize a struct-based adjacently tagged
301/// value of known type.
302///
303/// This visitor handles a struct-based adjacently tagged value, which is
304/// represented by a struct containing exactly two fields. The first field of
305/// this tuple is named according to tag-key and contains tag, the second field
306/// is named according to value-key and contains the value. Thus this visitor
307/// will return an error if the visited type is not a map or sequence with two
308/// entries.
309///
310/// `name` is the name with which the struct that will be serialized.
311///
312/// This visitor is intended for use of known values, i.e. when no tag-specific
313/// deserialization mehtod is required. Thus it does not need to cache values
314/// which can improve the performance.
315///
316/// # Note
317///
318/// If you do not need to choose a specific deserialization-method based on the
319/// tag, you should prefer this visitor to [`Visitor`](Visitor).
320pub struct KnownVisitor<T, V> {
321    tag_seed:   T,
322    value_seed: V,
323    tag_key:    &'static str,
324    value_key:  &'static str,
325}
326
327impl<T, V> KnownVisitor<T, V> {
328    /// Creates a new visitor with the given
329    /// [`SeedFactory`](::de::SeedFactory), tag-key and value-key.
330    pub fn new(tag_seed: T, value_seed: V, tag_key: &'static str, value_key: &'static str) -> Self {
331        KnownVisitor {
332            tag_seed,
333            value_seed,
334            tag_key,
335            value_key,
336        }
337    }
338}
339
340impl<'de, T, V> serde::de::Visitor<'de> for KnownVisitor<T, V>
341where
342    T: serde::de::DeserializeSeed<'de>,
343    V: serde::de::DeserializeSeed<'de>,
344{
345    type Value = (T::Value, V::Value);
346
347    fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
348        write!(fmt, "a struct with exactly two fields")
349    }
350
351    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
352    where
353        A: serde::de::MapAccess<'de>,
354    {
355        use serde::de::Error;
356
357        let key_1 = map.next_key_seed(KeySeed::new(self.tag_key, self.value_key))?
358            .ok_or_else(|| Error::invalid_length(0, &self))?;
359
360        match key_1 {
361            Key::Tag => {
362                let tag = map.next_value_seed(self.tag_seed)?;
363
364                let value_key = map.next_key_seed(KeySeed::new(self.tag_key, self.value_key))?
365                    .ok_or_else(|| Error::custom("missing value field"))?;
366
367                if value_key == Key::Value {
368                    Ok((tag, map.next_value_seed(self.value_seed)?))
369                } else {
370                    Err(Error::duplicate_field(self.tag_key))
371                }
372            },
373            Key::Value => {
374                let value = map.next_value_seed(self.value_seed)?;
375
376                let tag_key = map.next_key_seed(KeySeed::new(self.tag_key, self.value_key))?
377                    .ok_or_else(|| Error::custom("missing tag field"))?;
378
379                if tag_key == Key::Tag {
380                    Ok((map.next_value_seed(self.tag_seed)?, value))
381                } else {
382                    Err(Error::duplicate_field(self.value_key))
383                }
384            },
385        }
386    }
387
388    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
389    where
390        A: serde::de::SeqAccess<'de>,
391    {
392        use serde::de::Error;
393
394        let tag = seq.next_element_seed(self.tag_seed)?
395            .ok_or_else(|| Error::invalid_length(0, &"a struct with exactly two fields"))?;
396
397        let value = seq.next_element_seed(self.value_seed)?
398            .ok_or_else(|| Error::invalid_length(1, &"a struct with exactly two fields"))?;
399
400        Ok((tag, value))
401    }
402}
403
404
405#[derive(PartialEq)]
406enum Key {
407    Tag,
408    Value,
409}
410
411
412struct KeySeed {
413    tag_key:   &'static str,
414    value_key: &'static str,
415}
416
417impl KeySeed {
418    fn new(tag_key: &'static str, value_key: &'static str) -> Self {
419        KeySeed { tag_key, value_key }
420    }
421}
422
423impl<'de> serde::de::DeserializeSeed<'de> for KeySeed {
424    type Value = Key;
425
426    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
427    where
428        D: serde::Deserializer<'de>,
429    {
430        deserializer.deserialize_identifier(self)
431    }
432}
433
434impl<'de> serde::de::Visitor<'de> for KeySeed {
435    type Value = Key;
436
437    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
438        formatter.write_str("either the specified tag- or value-key")
439    }
440
441    fn visit_str<E>(self, value: &str) -> Result<Key, E>
442    where
443        E: serde::de::Error,
444    {
445        if value == self.tag_key {
446            Ok(Key::Tag)
447        } else if value == self.value_key {
448            Ok(Key::Value)
449        } else {
450            Err(serde::de::Error::custom(format_args!(
451                "invalid field name `{}`",
452                value
453            )))
454        }
455    }
456
457    fn visit_i64<E>(self, value: i64) -> Result<Key, E>
458    where
459        E: serde::de::Error,
460    {
461        if value == 0 {
462            Ok(Key::Tag)
463        } else if value == 1 {
464            Ok(Key::Value)
465        } else {
466            Err(serde::de::Error::custom(format_args!(
467                "invalid field id `{}`",
468                value
469            )))
470        }
471    }
472
473    fn visit_u64<E>(self, value: u64) -> Result<Key, E>
474    where
475        E: serde::de::Error,
476    {
477        if value == 0 {
478            Ok(Key::Tag)
479        } else if value == 1 {
480            Ok(Key::Value)
481        } else {
482            Err(serde::de::Error::custom(format_args!(
483                "invalid field id `{}`",
484                value
485            )))
486        }
487    }
488}