//! Implementation of the deserializer from attributes use std::borrow::Cow; use serde::de::{DeserializeSeed, Deserializer, Error, MapAccess, Visitor}; use serde::forward_to_deserialize_any; use crate::de::key::QNameDeserializer; use crate::de::SimpleTypeDeserializer; use crate::errors::serialize::DeError; use crate::events::attributes::Attributes; use crate::XmlVersion; impl<'i> Attributes<'i> { /// Converts this iterator into a serde's [`MapAccess`] trait to use with serde. /// The returned object also implements the [`Deserializer`] trait. /// /// # Parameters /// - `prefix`: a prefix of the field names in structs that should be stripped /// to get the local attribute name. The [`crate::de::Deserializer`] uses `"@"` /// as a prefix. /// /// # Example /// ``` /// # use pretty_assertions::assert_eq; /// use quick_xml::events::BytesStart; /// use quick_xml::XmlVersion; /// use serde::Deserialize; /// /// #[derive(Debug, PartialEq, Deserialize)] /// struct MyData<'i> { /// question: &'i str, /// answer: u32, /// } /// /// #[derive(Debug, PartialEq, Deserialize)] /// struct MyDataPrefixed<'i> { /// #[serde(rename = "@question")] question: &'i str, /// #[serde(rename = "@answer")] answer: u32, /// } /// /// let tag = BytesStart::from_content( /// "tag /// question = 'The Ultimate Question of Life, the Universe, and Everything' /// answer = '42'", /// 3 /// ); /// // Strip nothing from the field names /// let de = tag.attributes().clone().into_map_access(XmlVersion::Implicit1_0, ""); /// assert_eq!( /// MyData::deserialize(de).unwrap(), /// MyData { /// question: "The Ultimate Question of Life, the Universe, and Everything", /// answer: 42, /// } /// ); /// /// // Strip "@" from the field name /// let de = tag.attributes().into_map_access(XmlVersion::Implicit1_0, "@"); /// assert_eq!( /// MyDataPrefixed::deserialize(de).unwrap(), /// MyDataPrefixed { /// question: "The Ultimate Question of Life, the Universe, and Everything", /// answer: 42, /// } /// ); /// ``` #[inline] pub const fn into_map_access( self, version: XmlVersion, prefix: &'static str, ) -> AttributesDeserializer<'i> { AttributesDeserializer { iter: self, value: None, prefix, key_buf: String::new(), version, } } } //////////////////////////////////////////////////////////////////////////////////////////////////// /// A deserializer used to make possible to pack all attributes into a struct. /// It is created by [`Attributes::into_map_access`] method. /// /// This deserializer always call [`Visitor::visit_map`] with self as [`MapAccess`]. /// /// # Lifetime /// /// `'i` is a lifetime of the original buffer from which attributes were parsed. /// In particular, when reader was created from a string, this is lifetime of the /// string. #[derive(Debug, Clone)] pub struct AttributesDeserializer<'i> { iter: Attributes<'i>, /// The value of the attribute, read in last call to `next_key_seed`. value: Option>, /// This prefix will be stripped from struct fields before match against attribute name. prefix: &'static str, /// Buffer to store attribute name as a field name exposed to serde consumers. /// Kept in the deserializer to avoid many small allocations key_buf: String, version: XmlVersion, } impl<'de> Deserializer<'de> for AttributesDeserializer<'de> { type Error = DeError; #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { visitor.visit_map(self) } forward_to_deserialize_any! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any } } impl<'de> MapAccess<'de> for AttributesDeserializer<'de> { type Error = DeError; fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: DeserializeSeed<'de>, { debug_assert_eq!(self.value, None); match self.iter.next() { None => Ok(None), Some(Ok(attr)) => { self.value = Some(attr.value); self.key_buf.clear(); self.key_buf.push_str(self.prefix); let de = QNameDeserializer::from_attr(attr.key, self.iter.decoder(), &mut self.key_buf)?; seed.deserialize(de).map(Some) } Some(Err(err)) => Err(Error::custom(err)), } } fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { match self.value.take() { Some(value) => { let de = SimpleTypeDeserializer::from_attr( &value, 0..value.len(), self.version, self.iter.decoder(), ); seed.deserialize(de) } None => Err(DeError::KeyNotRead), } } }