1use crate::{
4 reader::{FromXml, XmlFromStr},
5 Error, Visitor,
6};
7use std::{
8 ops::{Deref, DerefMut},
9 str::FromStr,
10};
11use tokio::io::AsyncBufRead;
12
13#[derive(Debug, Clone, PartialEq)]
15pub struct XmlVec<T> {
16 items: Vec<T>,
17}
18
19impl<T, E> FromStr for XmlVec<T>
20where
21 T: FromStr<Err = E>,
22{
23 type Err = E;
24
25 fn from_str(s: &str) -> Result<Self, Self::Err> {
26 let mut items = Vec::new();
27 for split in s.split(' ') {
28 let item = T::from_str(split)?;
29 items.push(item);
30 }
31 Ok(Self { items })
32 }
33}
34
35impl<T> XmlFromStr for XmlVec<T> where T: FromStr {}
36
37impl<T> Deref for XmlVec<T> {
38 type Target = Vec<T>;
39
40 fn deref(&self) -> &Self::Target {
41 &self.items
42 }
43}
44
45impl<T> DerefMut for XmlVec<T> {
46 fn deref_mut(&mut self) -> &mut Self::Target {
47 &mut self.items
48 }
49}
50
51impl<T> From<XmlVec<T>> for Vec<T> {
52 fn from(v: XmlVec<T>) -> Self {
53 v.items
54 }
55}
56
57impl<T> From<Vec<T>> for XmlVec<T> {
58 fn from(v: Vec<T>) -> Self {
59 Self { items: v }
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Default)]
65pub struct XmlNode {
66 pub name: String,
68 pub attributes: Vec<XmlAttribute>,
70 pub text: Option<String>,
72 pub children: Vec<XmlNode>,
74}
75
76#[derive(Debug, Clone, PartialEq)]
78pub struct XmlAttribute {
79 pub name: String,
81 pub value: String,
83}
84
85#[async_trait::async_trait(?Send)]
86impl<B> Visitor<B> for XmlNode
87where
88 B: AsyncBufRead + Unpin,
89{
90 type Output = Self;
91
92 fn visit_tag(&mut self, name: &str) -> Result<(), Error> {
93 tracing::trace!("XmlNode deserializing element <{}>", name);
94 self.name = name.to_string();
95 Ok(())
96 }
97
98 fn visit_attribute(&mut self, name: &str, value: &str) -> Result<(), Error> {
99 self.attributes.push(XmlAttribute {
100 name: name.into(),
101 value: value.into(),
102 });
103 Ok(())
104 }
105
106 fn visit_text(&mut self, text: &str) -> Result<(), Error> {
107 self.text = Some(text.into());
108 Ok(())
109 }
110
111 async fn visit_child(
112 &mut self,
113 _name: &str,
114 reader: &mut crate::PeekingReader<B>,
115 ) -> Result<(), Error> {
116 self.children.push(
117 reader
118 .deserialize()
119 .await
120 .map_err(|e| Error::InnerDeserialiaztionError(self.name.clone(), Box::new(e)))?,
121 );
122 Ok(())
123 }
124
125 fn build(self) -> Result<Self::Output, Error> {
126 tracing::trace!("XmlNode done deserializing element <{}>", self.name);
127 Ok(self)
128 }
129}
130
131impl<B> FromXml<B> for XmlNode
132where
133 B: AsyncBufRead + Unpin,
134{
135 type Visitor = Self;
136}
137
138pub struct DiscardErrorVisitor<V, B>
143where
144 B: AsyncBufRead + Unpin,
145 V: Visitor<B>,
146{
147 inner_visitor: V,
148 _phantom: core::marker::PhantomData<B>,
149}
150
151impl<V, B> Default for DiscardErrorVisitor<V, B>
152where
153 B: AsyncBufRead + Unpin,
154 V: Visitor<B> + Default,
155{
156 fn default() -> Self {
157 Self {
158 inner_visitor: V::default(),
159 _phantom: core::marker::PhantomData,
160 }
161 }
162}
163
164#[async_trait::async_trait(?Send)]
165impl<V, B> Visitor<B> for DiscardErrorVisitor<V, B>
166where
167 B: AsyncBufRead + Unpin,
168 V: Visitor<B>,
169{
170 type Output = Option<V::Output>;
171
172 fn start_name() -> Option<&'static str> {
173 V::start_name()
174 }
175
176 fn visit_attribute(&mut self, name: &str, value: &str) -> Result<(), Error> {
177 self.inner_visitor.visit_attribute(name, value)
178 }
179
180 async fn visit_child(
181 &mut self,
182 name: &str,
183 reader: &mut crate::PeekingReader<B>,
184 ) -> Result<(), Error> {
185 self.inner_visitor.visit_child(name, reader).await
186 }
187
188 fn visit_text(&mut self, text: &str) -> Result<(), Error> {
189 self.inner_visitor.visit_text(text)
190 }
191
192 fn build(self) -> Result<Self::Output, Error> {
193 match self.inner_visitor.build() {
194 Ok(t) => Ok(Some(t)),
195 Err(e) => {
196 tracing::trace!("discarding build error: {:?}", e);
197 Ok(None)
198 }
199 }
200 }
201}