1 use std::io::Read;
2 
3 use serde::de::{self, IntoDeserializer, Unexpected};
4 use serde::forward_to_deserialize_any;
5 use xml::attribute::OwnedAttribute;
6 use xml::reader::XmlEvent;
7 
8 use crate::error::{Error, Result};
9 use crate::Deserializer;
10 
11 use super::buffer::BufferedXmlReader;
12 
13 pub struct MapAccess<'a, R: Read, B: BufferedXmlReader<R>> {
14     attrs: ::std::vec::IntoIter<OwnedAttribute>,
15     /// Cache of attribute value, populated when visitor calls `next_key_seed`; should be read & emptied straight after
16     /// by visitor call to `next_value_seed`
17     next_attr_value: Option<String>,
18     de: &'a mut Deserializer<R, B>,
19     /// Whether this `MapAccess` is to deserialize all inner contents of an outer element.
20     inner_value: bool,
21 }
22 
23 impl<'a, R: 'a + Read, B: BufferedXmlReader<R>> MapAccess<'a, R, B> {
new( de: &'a mut Deserializer<R, B>, attrs: Vec<OwnedAttribute>, inner_value: bool, ) -> Self24     pub fn new(
25         de: &'a mut Deserializer<R, B>,
26         attrs: Vec<OwnedAttribute>,
27         inner_value: bool,
28     ) -> Self {
29         MapAccess {
30             attrs: attrs.into_iter(),
31             next_attr_value: None,
32             de: de,
33             inner_value: inner_value,
34         }
35     }
36 }
37 
38 impl<'de, 'a, R: 'a + Read, B: BufferedXmlReader<R>> de::MapAccess<'de> for MapAccess<'a, R, B> {
39     type Error = Error;
40 
next_key_seed<K: de::DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>>41     fn next_key_seed<K: de::DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
42         debug_assert_eq!(self.next_attr_value, None);
43         match self.attrs.next() {
44             // Read all attributes first
45             Some(OwnedAttribute { name, value }) => {
46                 self.next_attr_value = Some(value);
47                 seed.deserialize(name.local_name.into_deserializer())
48                     .map(Some)
49             }
50             None => match *self.de.peek()? {
51                 XmlEvent::StartElement { ref name, .. } => seed
52                     .deserialize(
53                         if !self.inner_value {
54                             name.local_name.as_str()
55                         } else {
56                             "$value"
57                         }
58                         .into_deserializer(),
59                     )
60                     .map(Some),
61                 XmlEvent::Characters(_) => seed.deserialize("$value".into_deserializer()).map(Some),
62                 // Any other event: assume end of map values (actual check for `EndElement` done by the originating
63                 // `Deserializer`)
64                 _ => Ok(None),
65             },
66         }
67     }
68 
next_value_seed<V: de::DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value>69     fn next_value_seed<V: de::DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
70         match self.next_attr_value.take() {
71             Some(value) => seed.deserialize(AttrValueDeserializer(value)),
72             None => {
73                 if !self.inner_value {
74                     if let XmlEvent::StartElement { .. } = *self.de.peek()? {
75                         self.de.set_map_value();
76                     }
77                 }
78                 let result = seed.deserialize(&mut *self.de)?;
79                 Ok(result)
80             }
81         }
82     }
83 
size_hint(&self) -> Option<usize>84     fn size_hint(&self) -> Option<usize> {
85         self.attrs.size_hint().1
86     }
87 }
88 
89 struct AttrValueDeserializer(String);
90 
91 macro_rules! deserialize_type_attr {
92     ($deserialize:ident => $visit:ident) => {
93         fn $deserialize<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
94             visitor.$visit(self.0.parse()?)
95         }
96     };
97 }
98 
99 impl<'de> de::Deserializer<'de> for AttrValueDeserializer {
100     type Error = Error;
101 
deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value>102     fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
103         visitor.visit_string(self.0)
104     }
105 
106     deserialize_type_attr!(deserialize_i8 => visit_i8);
107     deserialize_type_attr!(deserialize_i16 => visit_i16);
108     deserialize_type_attr!(deserialize_i32 => visit_i32);
109     deserialize_type_attr!(deserialize_i64 => visit_i64);
110     deserialize_type_attr!(deserialize_u8 => visit_u8);
111     deserialize_type_attr!(deserialize_u16 => visit_u16);
112     deserialize_type_attr!(deserialize_u32 => visit_u32);
113     deserialize_type_attr!(deserialize_u64 => visit_u64);
114     deserialize_type_attr!(deserialize_f32 => visit_f32);
115     deserialize_type_attr!(deserialize_f64 => visit_f64);
116 
deserialize_enum<V: de::Visitor<'de>>( self, _name: &str, _variants: &'static [&'static str], visitor: V, ) -> Result<V::Value>117     fn deserialize_enum<V: de::Visitor<'de>>(
118         self,
119         _name: &str,
120         _variants: &'static [&'static str],
121         visitor: V,
122     ) -> Result<V::Value> {
123         visitor.visit_enum(self.0.into_deserializer())
124     }
125 
deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value>126     fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
127         visitor.visit_some(self)
128     }
129 
deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value>130     fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
131         match self.0.as_str() {
132             "true" | "1" => visitor.visit_bool(true),
133             "false" | "0" => visitor.visit_bool(false),
134             _ => Err(de::Error::invalid_value(
135                 Unexpected::Str(&self.0),
136                 &"a boolean",
137             )),
138         }
139     }
140 
141     forward_to_deserialize_any! {
142         char str string unit seq bytes map unit_struct newtype_struct tuple_struct
143         struct identifier tuple ignored_any byte_buf
144     }
145 }
146