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