1 //! Serde `Deserializer` module
2 
3 use crate::{
4     de::{escape::EscapedDeserializer, Deserializer, INNER_VALUE},
5     errors::serialize::DeError,
6     events::{attributes::Attribute, BytesStart, Event},
7 };
8 use serde::de::{self, DeserializeSeed, IntoDeserializer};
9 use std::io::BufRead;
10 
11 enum MapValue {
12     Empty,
13     Attribute { value: Vec<u8> },
14     Nested,
15     InnerValue,
16 }
17 
18 /// A deserializer for `Attributes`
19 pub(crate) struct MapAccess<'a, R: BufRead> {
20     /// Tag -- owner of attributes
21     start: BytesStart<'static>,
22     de: &'a mut Deserializer<R>,
23     /// Position in flat byte slice of all attributes from which next
24     /// attribute should be parsed. This field is required because we
25     /// do not store reference to `Attributes` itself but instead create
26     /// a new object on each advance of `Attributes` iterator, so we need
27     /// to restore last position before advance.
28     position: usize,
29     value: MapValue,
30 }
31 
32 impl<'a, R: BufRead> MapAccess<'a, R> {
33     /// Create a new MapAccess
new(de: &'a mut Deserializer<R>, start: BytesStart<'static>) -> Result<Self, DeError>34     pub fn new(de: &'a mut Deserializer<R>, start: BytesStart<'static>) -> Result<Self, DeError> {
35         let position = start.attributes().position;
36         Ok(MapAccess {
37             de,
38             start,
39             position,
40             value: MapValue::Empty,
41         })
42     }
43 
next_attr(&mut self) -> Result<Option<Attribute>, DeError>44     fn next_attr(&mut self) -> Result<Option<Attribute>, DeError> {
45         let mut attributes = self.start.attributes();
46         attributes.position = self.position;
47         let next_att = attributes.next();
48         self.position = attributes.position;
49         Ok(next_att.transpose()?)
50     }
51 }
52 
53 impl<'a, 'de, R: BufRead> de::MapAccess<'de> for MapAccess<'a, R> {
54     type Error = DeError;
55 
next_key_seed<K: DeserializeSeed<'de>>( &mut self, seed: K, ) -> Result<Option<K::Value>, Self::Error>56     fn next_key_seed<K: DeserializeSeed<'de>>(
57         &mut self,
58         seed: K,
59     ) -> Result<Option<K::Value>, Self::Error> {
60         let attr_key_val = self
61             .next_attr()?
62             .map(|a| (a.key.to_owned(), a.value.into_owned()));
63         let decoder = self.de.reader.decoder();
64         let has_value_field = self.de.has_value_field;
65         if let Some((key, value)) = attr_key_val {
66             // try getting map from attributes (key= "value")
67             self.value = MapValue::Attribute { value };
68             seed.deserialize(EscapedDeserializer::new(key, decoder, false))
69                 .map(Some)
70         } else {
71             // try getting from events (<key>value</key>)
72             match self.de.peek()? {
73                 Some(Event::Text(_)) => {
74                     self.value = MapValue::InnerValue;
75                     seed.deserialize(INNER_VALUE.into_deserializer()).map(Some)
76                 }
77                 // Used to deserialize collections of enums, like:
78                 // <root>
79                 //   <A/>
80                 //   <B/>
81                 //   <C/>
82                 // </root>
83                 //
84                 // into
85                 //
86                 // enum Enum { A, B, С }
87                 // struct Root {
88                 //     #[serde(rename = "$value")]
89                 //     items: Vec<Enum>,
90                 // }
91                 // TODO: This should be handled by #[serde(flatten)]
92                 // See https://github.com/serde-rs/serde/issues/1905
93                 Some(Event::Start(_)) if has_value_field => {
94                     self.value = MapValue::InnerValue;
95                     seed.deserialize(INNER_VALUE.into_deserializer()).map(Some)
96                 }
97                 Some(Event::Start(e)) => {
98                     let name = e.local_name().to_owned();
99                     self.value = MapValue::Nested;
100                     seed.deserialize(EscapedDeserializer::new(name, decoder, false))
101                         .map(Some)
102                 }
103                 _ => Ok(None),
104             }
105         }
106     }
107 
next_value_seed<K: DeserializeSeed<'de>>( &mut self, seed: K, ) -> Result<K::Value, Self::Error>108     fn next_value_seed<K: DeserializeSeed<'de>>(
109         &mut self,
110         seed: K,
111     ) -> Result<K::Value, Self::Error> {
112         match std::mem::replace(&mut self.value, MapValue::Empty) {
113             MapValue::Attribute { value } => seed.deserialize(EscapedDeserializer::new(
114                 value,
115                 self.de.reader.decoder(),
116                 true,
117             )),
118             MapValue::Nested | MapValue::InnerValue => seed.deserialize(&mut *self.de),
119             MapValue::Empty => Err(DeError::EndOfAttributes),
120         }
121     }
122 }
123