quick_xml/de/
var.rs

1use crate::{
2    de::key::QNameDeserializer,
3    de::map::ElementMapAccess,
4    de::resolver::EntityResolver,
5    de::simple_type::SimpleTypeDeserializer,
6    de::{DeEvent, Deserializer, XmlRead, TEXT_KEY},
7    errors::serialize::DeError,
8};
9use serde::de::value::BorrowedStrDeserializer;
10use serde::de::{self, DeserializeSeed, Deserializer as _, Visitor};
11
12/// An enum access
13pub struct EnumAccess<'de, 'd, R, E>
14where
15    R: XmlRead<'de>,
16    E: EntityResolver,
17{
18    de: &'d mut Deserializer<'de, R, E>,
19}
20
21impl<'de, 'd, R, E> EnumAccess<'de, 'd, R, E>
22where
23    R: XmlRead<'de>,
24    E: EntityResolver,
25{
26    pub fn new(de: &'d mut Deserializer<'de, R, E>) -> Self {
27        EnumAccess { de }
28    }
29}
30
31impl<'de, 'd, R, E> de::EnumAccess<'de> for EnumAccess<'de, 'd, R, E>
32where
33    R: XmlRead<'de>,
34    E: EntityResolver,
35{
36    type Error = DeError;
37    type Variant = VariantAccess<'de, 'd, R, E>;
38
39    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
40    where
41        V: DeserializeSeed<'de>,
42    {
43        let decoder = self.de.reader.decoder();
44        let (name, is_text) = match self.de.peek()? {
45            DeEvent::Start(e) => (
46                seed.deserialize(QNameDeserializer::from_elem(e.raw_name(), decoder)?)?,
47                false,
48            ),
49            DeEvent::Text(_) => (
50                seed.deserialize(BorrowedStrDeserializer::<DeError>::new(TEXT_KEY))?,
51                true,
52            ),
53            DeEvent::End(e) => return Err(DeError::UnexpectedEnd(e.name().into_inner().to_vec())),
54            DeEvent::Eof => return Err(DeError::UnexpectedEof),
55        };
56        Ok((
57            name,
58            VariantAccess {
59                de: self.de,
60                is_text,
61            },
62        ))
63    }
64}
65
66pub struct VariantAccess<'de, 'd, R, E>
67where
68    R: XmlRead<'de>,
69    E: EntityResolver,
70{
71    de: &'d mut Deserializer<'de, R, E>,
72    /// `true` if variant should be deserialized from a textual content
73    /// and `false` if from tag
74    is_text: bool,
75}
76
77impl<'de, 'd, R, E> de::VariantAccess<'de> for VariantAccess<'de, 'd, R, E>
78where
79    R: XmlRead<'de>,
80    E: EntityResolver,
81{
82    type Error = DeError;
83
84    fn unit_variant(self) -> Result<(), Self::Error> {
85        match self.de.next()? {
86            // Consume subtree
87            DeEvent::Start(e) => self.de.read_to_end(e.name()),
88            // Does not needed to deserialize using SimpleTypeDeserializer, because
89            // it returns `()` when `deserialize_unit()` is requested
90            DeEvent::Text(_) => Ok(()),
91            // SAFETY: the other events are filtered in `variant_seed()`
92            _ => unreachable!("Only `Start` or `Text` events are possible here"),
93        }
94    }
95
96    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
97    where
98        T: DeserializeSeed<'de>,
99    {
100        if self.is_text {
101            match self.de.next()? {
102                DeEvent::Text(e) => seed.deserialize(SimpleTypeDeserializer::from_text_content(e)),
103                // SAFETY: the other events are filtered in `variant_seed()`
104                _ => unreachable!("Only `Text` events are possible here"),
105            }
106        } else {
107            seed.deserialize(self.de)
108        }
109    }
110
111    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
112    where
113        V: Visitor<'de>,
114    {
115        if self.is_text {
116            match self.de.next()? {
117                DeEvent::Text(e) => {
118                    SimpleTypeDeserializer::from_text_content(e).deserialize_tuple(len, visitor)
119                }
120                // SAFETY: the other events are filtered in `variant_seed()`
121                _ => unreachable!("Only `Text` events are possible here"),
122            }
123        } else {
124            self.de.deserialize_tuple(len, visitor)
125        }
126    }
127
128    fn struct_variant<V>(
129        self,
130        fields: &'static [&'static str],
131        visitor: V,
132    ) -> Result<V::Value, Self::Error>
133    where
134        V: Visitor<'de>,
135    {
136        match self.de.next()? {
137            DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self.de, e, fields)?),
138            DeEvent::Text(e) => {
139                SimpleTypeDeserializer::from_text_content(e).deserialize_struct("", fields, visitor)
140            }
141            // SAFETY: the other events are filtered in `variant_seed()`
142            _ => unreachable!("Only `Start` or `Text` events are possible here"),
143        }
144    }
145}