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> {
#[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,
}
}
}
#[derive(Debug, Clone)]
pub struct AttributesDeserializer<'i> {
iter: Attributes<'i>,
value: Option<Cow<'i, [u8]>>,
prefix: &'static str,
key_buf: String,
version: XmlVersion,
}
impl<'de> Deserializer<'de> for AttributesDeserializer<'de> {
type Error = DeError;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
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<K>(&mut self, seed: K) -> Result<Option<K::Value>, 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<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
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),
}
}
}