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