serde_tagged/de/
internal.rs

1//! Deserialization of internally tagged values.
2//!
3//! See [`ser::internal`](::ser::internal) for a description of this tagging
4//! format.
5//!
6//! # Warning
7//!
8//! Deserialization of internally tagged values requires a self-describing
9//! data format.
10
11use de::seed::SeedFactory;
12use util::de::content::{Content, ContentDeserializer, ContentVisitor};
13
14use std;
15use std::marker::PhantomData;
16
17use serde;
18
19
20/// Deserialize an internally tagged value.
21///
22/// The deserializer controls the underlying data format while the seed-factory
23/// specifies the instructions (depending on the tag) on how the value should be
24/// deserialized.
25///
26/// See [`de`](::de) for more information on
27/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
28///
29/// See [`deserialize_seed`](deserialize_seed) for a version that allows you to
30/// pass a `DeserializeSeed` to deserialize the tag. This version is equivalent
31/// to `deserialize_seed(deserializer, tag_key, seed_factory, PhantomData<T>)`
32pub fn deserialize<'de, T, D, F>(
33    deserializer: D,
34    tag_key: &'static str,
35    seed_factory: F,
36) -> Result<F::Value, D::Error>
37where
38    T: serde::Deserialize<'de>,
39    D: serde::Deserializer<'de>,
40    F: SeedFactory<'de, T>,
41{
42    deserialize_seed(deserializer, tag_key, seed_factory, PhantomData::<T>)
43}
44
45
46/// Deserialize an internally tagged value with the given tag-seed.
47///
48/// The deserializer controls the underlying data format while the seed-factory
49/// specifies the instructions (depending on the tag) on how the value should be
50/// deserialized.
51///
52/// See [`de`](::de) for more information on
53/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
54pub fn deserialize_seed<'de, D, F, S>(
55    deserializer: D,
56    tag_key: &'static str,
57    seed_factory: F,
58    tag_seed: S,
59) -> Result<F::Value, D::Error>
60where
61    D: serde::Deserializer<'de>,
62    F: SeedFactory<'de, S::Value>,
63    S: serde::de::DeserializeSeed<'de>,
64{
65    deserializer.deserialize_any(Visitor::new(tag_key, seed_factory, tag_seed))
66}
67
68
69/// A visitor that can be used to deserialize an externally tagged value.
70///
71/// This visitor handles an externally tagged value, which is represented by a
72/// map containing a single entry, where the key is the tag and the value is the
73/// value that should be deserialized. Thus it will return an error if the
74/// visited type is not a map.
75///
76/// The [`SeedFactory`](::de::SeedFactory) provided to this visitor
77/// provides a `serde::de::DeserializeSeed` implementation depending on the tag,
78/// which then determines how the value is going to be deserialized.
79///
80/// See [`de`](::de) for more information on
81/// [`SeedFactory`](::de::SeedFactory) and implementations thereof.
82pub struct Visitor<F, S> {
83    seed_factory: F,
84    tag_seed:     S,
85    tag_key:      &'static str,
86}
87
88impl<F, S> Visitor<F, S> {
89    /// Creates a new visitor with the given tag-key and
90    /// [`SeedFactory`](::de::SeedFactory).
91    pub fn new(tag_key: &'static str, seed_factory: F, tag_seed: S) -> Self {
92        Visitor {
93            seed_factory,
94            tag_seed,
95            tag_key,
96        }
97    }
98}
99
100impl<'de, F, S> serde::de::Visitor<'de> for Visitor<F, S>
101where
102    F: SeedFactory<'de, S::Value>,
103    S: serde::de::DeserializeSeed<'de>,
104{
105    type Value = F::Value;
106
107    fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
108        write!(fmt, "a tagged value")
109    }
110
111    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
112    where
113        A: serde::de::SeqAccess<'de>,
114    {
115        use serde::de::DeserializeSeed;
116
117        let (tag, val) = TaggedValueVisitor::new(self.tag_key).visit_seq(seq)?;
118
119        self.seed_factory
120            .seed(self.tag_seed.deserialize(ContentDeserializer::new(tag))?)?
121            .deserialize(ContentDeserializer::new(val))
122    }
123
124    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
125    where
126        A: serde::de::MapAccess<'de>,
127    {
128        use serde::de::DeserializeSeed;
129
130        let (tag, val) = TaggedValueVisitor::new(self.tag_key).visit_map(map)?;
131
132        self.seed_factory
133            .seed(self.tag_seed.deserialize(ContentDeserializer::new(tag))?)?
134            .deserialize(ContentDeserializer::new(val))
135    }
136}
137
138
139struct TaggedValueVisitor {
140    tag_key: &'static str,
141}
142
143impl TaggedValueVisitor {
144    fn new(tag_key: &'static str) -> Self {
145        TaggedValueVisitor { tag_key }
146    }
147}
148
149impl<'de> serde::de::Visitor<'de> for TaggedValueVisitor {
150    type Value = (Content<'de>, Content<'de>);
151
152    fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
153        write!(fmt, "a tagged value")
154    }
155
156    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
157    where
158        A: serde::de::SeqAccess<'de>,
159    {
160        use serde::de::value::SeqAccessDeserializer;
161        use serde::de::{Deserialize, Error};
162
163        let tag: Content = seq
164            .next_element()?
165            .ok_or_else(|| Error::missing_field(self.tag_key))?;
166
167        let val = Content::deserialize(SeqAccessDeserializer::new(seq))?;
168
169        Ok((tag, val))
170    }
171
172    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
173    where
174        A: serde::de::MapAccess<'de>,
175    {
176        use serde::de::Error;
177
178        let mut tag = None;
179        let mut val = Vec::with_capacity(map.size_hint().unwrap_or(128));
180
181        while let Some(key) = map.next_key_seed(TagOrValueSeed::new(self.tag_key))? {
182            match key {
183                TagOrValue::Tag => {
184                    if tag.is_some() {
185                        return Err(Error::duplicate_field(self.tag_key));
186                    }
187                    tag = Some(map.next_value()?);
188                },
189                TagOrValue::Value(key) => {
190                    val.push((key, map.next_value()?));
191                },
192            }
193        }
194
195        let tag = tag.ok_or_else(|| Error::missing_field(self.tag_key))?;
196
197        Ok((tag, Content::Map(val)))
198    }
199}
200
201
202enum TagOrValue<'de> {
203    Tag,
204    Value(Content<'de>),
205}
206
207
208struct TagOrValueSeed {
209    tag_key: &'static str,
210}
211
212impl TagOrValueSeed {
213    fn new(tag_key: &'static str) -> Self {
214        TagOrValueSeed { tag_key }
215    }
216}
217
218impl<'de> serde::de::DeserializeSeed<'de> for TagOrValueSeed {
219    type Value = TagOrValue<'de>;
220
221    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
222    where
223        D: serde::de::Deserializer<'de>,
224    {
225        deserializer.deserialize_any(self)
226    }
227}
228
229impl<'de> serde::de::Visitor<'de> for TagOrValueSeed {
230    type Value = TagOrValue<'de>;
231
232    fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
233        write!(fmt, "a tag `{}` or any other value", self.tag_key)
234    }
235
236    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
237    where
238        E: serde::de::Error,
239    {
240        ContentVisitor::new().visit_bool(v).map(TagOrValue::Value)
241    }
242
243    fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
244    where
245        E: serde::de::Error,
246    {
247        ContentVisitor::new().visit_i8(v).map(TagOrValue::Value)
248    }
249
250    fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
251    where
252        E: serde::de::Error,
253    {
254        ContentVisitor::new().visit_i16(v).map(TagOrValue::Value)
255    }
256
257    fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
258    where
259        E: serde::de::Error,
260    {
261        ContentVisitor::new().visit_i32(v).map(TagOrValue::Value)
262    }
263
264    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
265    where
266        E: serde::de::Error,
267    {
268        ContentVisitor::new().visit_i64(v).map(TagOrValue::Value)
269    }
270
271    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
272    where
273        E: serde::de::Error,
274    {
275        ContentVisitor::new().visit_u8(v).map(TagOrValue::Value)
276    }
277
278    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
279    where
280        E: serde::de::Error,
281    {
282        ContentVisitor::new().visit_u16(v).map(TagOrValue::Value)
283    }
284
285    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
286    where
287        E: serde::de::Error,
288    {
289        ContentVisitor::new().visit_u32(v).map(TagOrValue::Value)
290    }
291
292    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
293    where
294        E: serde::de::Error,
295    {
296        ContentVisitor::new().visit_u64(v).map(TagOrValue::Value)
297    }
298
299    fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
300    where
301        E: serde::de::Error,
302    {
303        ContentVisitor::new().visit_f32(v).map(TagOrValue::Value)
304    }
305
306    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
307    where
308        E: serde::de::Error,
309    {
310        ContentVisitor::new().visit_f64(v).map(TagOrValue::Value)
311    }
312
313    fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
314    where
315        E: serde::de::Error,
316    {
317        ContentVisitor::new().visit_char(v).map(TagOrValue::Value)
318    }
319
320    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
321    where
322        E: serde::de::Error,
323    {
324        if v == self.tag_key {
325            Ok(TagOrValue::Tag)
326        } else {
327            ContentVisitor::new().visit_str(v).map(TagOrValue::Value)
328        }
329    }
330
331    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
332    where
333        E: serde::de::Error,
334    {
335        if v == self.tag_key {
336            Ok(TagOrValue::Tag)
337        } else {
338            ContentVisitor::new()
339                .visit_borrowed_str(v)
340                .map(TagOrValue::Value)
341        }
342    }
343
344    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
345    where
346        E: serde::de::Error,
347    {
348        if v == self.tag_key {
349            Ok(TagOrValue::Tag)
350        } else {
351            ContentVisitor::new().visit_string(v).map(TagOrValue::Value)
352        }
353    }
354
355    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
356    where
357        E: serde::de::Error,
358    {
359        if v == self.tag_key.as_bytes() {
360            Ok(TagOrValue::Tag)
361        } else {
362            ContentVisitor::new().visit_bytes(v).map(TagOrValue::Value)
363        }
364    }
365
366    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
367    where
368        E: serde::de::Error,
369    {
370        if v == self.tag_key.as_bytes() {
371            Ok(TagOrValue::Tag)
372        } else {
373            ContentVisitor::new()
374                .visit_borrowed_bytes(v)
375                .map(TagOrValue::Value)
376        }
377    }
378
379    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
380    where
381        E: serde::de::Error,
382    {
383        if v == self.tag_key.as_bytes() {
384            Ok(TagOrValue::Tag)
385        } else {
386            ContentVisitor::new()
387                .visit_byte_buf(v)
388                .map(TagOrValue::Value)
389        }
390    }
391
392    fn visit_none<E>(self) -> Result<Self::Value, E>
393    where
394        E: serde::de::Error,
395    {
396        ContentVisitor::new().visit_none().map(TagOrValue::Value)
397    }
398
399    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
400    where
401        D: serde::de::Deserializer<'de>,
402    {
403        ContentVisitor::new()
404            .visit_some(deserializer)
405            .map(TagOrValue::Value)
406    }
407
408    fn visit_unit<E>(self) -> Result<Self::Value, E>
409    where
410        E: serde::de::Error,
411    {
412        ContentVisitor::new().visit_unit().map(TagOrValue::Value)
413    }
414
415    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
416    where
417        D: serde::de::Deserializer<'de>,
418    {
419        ContentVisitor::new()
420            .visit_newtype_struct(deserializer)
421            .map(TagOrValue::Value)
422    }
423
424    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
425    where
426        A: serde::de::SeqAccess<'de>,
427    {
428        ContentVisitor::new().visit_seq(seq).map(TagOrValue::Value)
429    }
430
431    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
432    where
433        A: serde::de::MapAccess<'de>,
434    {
435        ContentVisitor::new().visit_map(map).map(TagOrValue::Value)
436    }
437
438    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
439    where
440        A: serde::de::EnumAccess<'de>,
441    {
442        ContentVisitor::new()
443            .visit_enum(data)
444            .map(TagOrValue::Value)
445    }
446}