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            // SAFETY: The reader is guaranteed that we don't have unmatched tags
54            // If we here, then out deserializer has a bug
55            DeEvent::End(e) => unreachable!("{:?}", e),
56            DeEvent::Eof => return Err(DeError::UnexpectedEof),
57        };
58        Ok((
59            name,
60            VariantAccess {
61                de: self.de,
62                is_text,
63            },
64        ))
65    }
66}
67
68pub struct VariantAccess<'de, 'd, R, E>
69where
70    R: XmlRead<'de>,
71    E: EntityResolver,
72{
73    de: &'d mut Deserializer<'de, R, E>,
74    /// `true` if variant should be deserialized from a textual content
75    /// and `false` if from tag
76    is_text: bool,
77}
78
79impl<'de, 'd, R, E> de::VariantAccess<'de> for VariantAccess<'de, 'd, R, E>
80where
81    R: XmlRead<'de>,
82    E: EntityResolver,
83{
84    type Error = DeError;
85
86    fn unit_variant(self) -> Result<(), Self::Error> {
87        match self.de.next()? {
88            // Consume subtree
89            DeEvent::Start(e) => self.de.read_to_end(e.name()),
90            // Does not needed to deserialize using SimpleTypeDeserializer, because
91            // it returns `()` when `deserialize_unit()` is requested
92            DeEvent::Text(_) => Ok(()),
93            // SAFETY: the other events are filtered in `variant_seed()`
94            _ => unreachable!("Only `Start` or `Text` events are possible here"),
95        }
96    }
97
98    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
99    where
100        T: DeserializeSeed<'de>,
101    {
102        if self.is_text {
103            match self.de.next()? {
104                DeEvent::Text(e) => seed.deserialize(SimpleTypeDeserializer::from_text_content(e)),
105                // SAFETY: the other events are filtered in `variant_seed()`
106                _ => unreachable!("Only `Text` events are possible here"),
107            }
108        } else {
109            seed.deserialize(self.de)
110        }
111    }
112
113    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
114    where
115        V: Visitor<'de>,
116    {
117        if self.is_text {
118            match self.de.next()? {
119                DeEvent::Text(e) => {
120                    SimpleTypeDeserializer::from_text_content(e).deserialize_tuple(len, visitor)
121                }
122                // SAFETY: the other events are filtered in `variant_seed()`
123                _ => unreachable!("Only `Text` events are possible here"),
124            }
125        } else {
126            self.de.deserialize_tuple(len, visitor)
127        }
128    }
129
130    fn struct_variant<V>(
131        self,
132        fields: &'static [&'static str],
133        visitor: V,
134    ) -> Result<V::Value, Self::Error>
135    where
136        V: Visitor<'de>,
137    {
138        match self.de.next()? {
139            DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self.de, e, fields)?),
140            DeEvent::Text(e) => {
141                SimpleTypeDeserializer::from_text_content(e).deserialize_struct("", fields, visitor)
142            }
143            // SAFETY: the other events are filtered in `variant_seed()`
144            _ => unreachable!("Only `Start` or `Text` events are possible here"),
145        }
146    }
147}