1use super::{FromXml, PeekingReader, Visitor};
4use crate::Error;
5use std::{marker::PhantomData, str::FromStr};
6use tokio::io::AsyncBufRead;
7
8impl<B, T> FromXml<B> for Option<T>
9where
10 B: AsyncBufRead + Unpin,
11 T: FromXml<B>,
12{
13 type Visitor = OptionalVisitor<T, B>;
14}
15
16pub struct OptionalVisitor<T, B>
21where
22 B: AsyncBufRead + Unpin,
23 T: FromXml<B>,
24{
25 empty: bool,
26 inner_visitor: T::Visitor,
27}
28
29impl<T, B> Default for OptionalVisitor<T, B>
30where
31 B: AsyncBufRead + Unpin,
32 T: FromXml<B>,
33{
34 fn default() -> Self {
35 Self {
36 empty: true,
37 inner_visitor: T::Visitor::default(),
38 }
39 }
40}
41
42#[async_trait::async_trait(?Send)]
43impl<B, T> Visitor<B> for OptionalVisitor<T, B>
44where
45 B: AsyncBufRead + Unpin,
46 T: FromXml<B>,
47{
48 type Output = Option<T>;
49
50 fn start_name() -> Option<&'static str> {
51 T::Visitor::start_name()
52 }
53
54 fn visit_attribute(&mut self, name: &str, value: &str) -> Result<(), Error> {
55 self.empty = false;
56 self.inner_visitor.visit_attribute(name, value)
57 }
58
59 async fn visit_child(
60 &mut self,
61 name: &str,
62 reader: &mut PeekingReader<B>,
63 ) -> Result<(), Error> {
64 self.empty = false;
65 self.inner_visitor.visit_child(name, reader).await
66 }
67
68 fn visit_text(&mut self, text: &str) -> Result<(), Error> {
69 self.empty = false;
70 self.inner_visitor.visit_text(text)
71 }
72
73 fn build(self) -> Result<Self::Output, Error> {
74 match self.inner_visitor.build() {
75 Ok(t) => Ok(Some(t)),
76 Err(_) if self.empty => Ok(None),
77 Err(e) => Err(e),
78 }
79 }
80}
81
82pub trait XmlFromStr {}
84
85impl<B, T, E> FromXml<B> for T
86where
87 B: AsyncBufRead + Unpin,
88 T: XmlFromStr + FromStr<Err = E>,
89 E: std::fmt::Display,
90{
91 type Visitor = FromStringVisitor<T>;
92}
93
94pub struct FromStringVisitor<T>
98where
99 T: FromStr,
100{
101 data: Option<T>,
102}
103
104impl<T, E> Default for FromStringVisitor<T>
105where
106 T: XmlFromStr + FromStr<Err = E>,
107 E: std::fmt::Display,
108{
109 fn default() -> Self {
110 Self { data: None }
111 }
112}
113
114#[async_trait::async_trait(?Send)]
115impl<B, T, E> Visitor<B> for FromStringVisitor<T>
116where
117 B: AsyncBufRead + Unpin,
118 T: XmlFromStr + FromStr<Err = E>,
119 E: std::fmt::Display,
120{
121 type Output = T;
122
123 fn start_name() -> Option<&'static str> {
124 None
125 }
126
127 fn visit_text(&mut self, text: &str) -> Result<(), Error> {
128 if self.data.is_some() {
129 return Err(Error::DoubleText);
130 }
131 match T::from_str(text) {
132 Ok(t) => self.data = Some(t),
133 Err(e) => return Err(Error::Deserialization(e.to_string())),
134 }
135 Ok(())
136 }
137
138 fn build(self) -> Result<Self::Output, Error> {
139 let data = if let Some(data) = self.data {
140 data
141 } else {
142 return Err(Error::MissingText);
143 };
144 Ok(data)
145 }
146}
147
148pub struct FromVisitor<B, Target, FromType>
151where
152 B: AsyncBufRead + Unpin,
153 Target: From<FromType>,
154 FromType: FromXml<B>,
155{
156 inner: FromType::Visitor,
157 _target: PhantomData<Target>,
158}
159
160impl<B, Target, FromType> Default for FromVisitor<B, Target, FromType>
161where
162 B: AsyncBufRead + Unpin,
163 Target: From<FromType>,
164 FromType: FromXml<B>,
165{
166 fn default() -> Self {
167 Self {
168 inner: FromType::Visitor::default(),
169 _target: PhantomData,
170 }
171 }
172}
173
174#[async_trait::async_trait(?Send)]
175impl<B, Target, FromType> Visitor<B> for FromVisitor<B, Target, FromType>
176where
177 B: AsyncBufRead + Unpin,
178 Target: From<FromType>,
179 FromType: FromXml<B>,
180{
181 type Output = Target;
182
183 fn start_name() -> Option<&'static str> {
184 None
185 }
186
187 fn visit_tag(&mut self, name: &str) -> Result<(), Error> {
188 self.inner.visit_tag(name)
189 }
190
191 fn visit_text(&mut self, text: &str) -> Result<(), Error> {
192 self.inner.visit_text(text)
193 }
194
195 fn visit_attribute(&mut self, name: &str, value: &str) -> Result<(), Error> {
196 self.inner.visit_attribute(name, value)
197 }
198
199 async fn visit_child(
200 &mut self,
201 name: &str,
202 reader: &mut PeekingReader<B>,
203 ) -> Result<(), Error> {
204 self.inner.visit_child(name, reader).await
205 }
206
207 fn build(self) -> Result<Self::Output, Error> {
208 let from = self.inner.build()?;
209 Ok(from.into())
210 }
211}
212
213pub struct TryFromVisitor<B, Target, FromType, E>
216where
217 B: AsyncBufRead + Unpin,
218 Target: TryFrom<FromType, Error = E>,
219 FromType: FromXml<B>,
220{
221 inner: FromType::Visitor,
222 _target: PhantomData<Target>,
223}
224
225impl<B, Target, FromType, E> Default for TryFromVisitor<B, Target, FromType, E>
226where
227 B: AsyncBufRead + Unpin,
228 Target: TryFrom<FromType, Error = E>,
229 FromType: FromXml<B>,
230{
231 fn default() -> Self {
232 Self {
233 inner: FromType::Visitor::default(),
234 _target: PhantomData,
235 }
236 }
237}
238
239#[async_trait::async_trait(?Send)]
240impl<B, Target, FromType, E> Visitor<B> for TryFromVisitor<B, Target, FromType, E>
241where
242 B: AsyncBufRead + Unpin,
243 Target: TryFrom<FromType, Error = E>,
244 FromType: FromXml<B>,
245 E: std::fmt::Display,
246{
247 type Output = Target;
248
249 fn start_name() -> Option<&'static str> {
250 None
251 }
252
253 fn visit_tag(&mut self, name: &str) -> Result<(), Error> {
254 self.inner.visit_tag(name)
255 }
256
257 fn visit_text(&mut self, text: &str) -> Result<(), Error> {
258 self.inner.visit_text(text)
259 }
260
261 fn visit_attribute(&mut self, name: &str, value: &str) -> Result<(), Error> {
262 self.inner.visit_attribute(name, value)
263 }
264
265 async fn visit_child(
266 &mut self,
267 name: &str,
268 reader: &mut PeekingReader<B>,
269 ) -> Result<(), Error> {
270 self.inner.visit_child(name, reader).await
271 }
272
273 fn build(self) -> Result<Self::Output, Error> {
274 let from = self.inner.build()?;
275 from.try_into()
276 .map_err(|e| Error::Deserialization(format!("error converting: {}", e)))
277 }
278}
279
280impl XmlFromStr for String {}
281impl XmlFromStr for i8 {}
282impl XmlFromStr for i16 {}
283impl XmlFromStr for i32 {}
284impl XmlFromStr for i64 {}
285impl XmlFromStr for u8 {}
286impl XmlFromStr for u16 {}
287impl XmlFromStr for u32 {}
288impl XmlFromStr for u64 {}
289impl XmlFromStr for u128 {}
290impl XmlFromStr for bool {}
291impl XmlFromStr for char {}
292impl XmlFromStr for &str {}
293
294impl<T: XmlFromStr> XmlFromStr for &'static T {}