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