1use std::fmt::Debug;
2use std::marker::PhantomData;
3use std::str::{from_utf8, FromStr};
4
5use quick_xml::events::Event;
6
7use super::{Error, ErrorKind, XmlReader, XmlReaderSync};
8
9pub trait WithDeserializer: Sized {
11 type Deserializer: for<'de> Deserializer<'de, Self>;
13}
14
15impl<X> WithDeserializer for X
16where
17 X: DeserializeBytes + Debug,
18{
19 type Deserializer = ContentDeserializer<X>;
20}
21
22pub trait Deserializer<'de, T>: Debug + Sized {
25 fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, T, Self>
31 where
32 R: XmlReader;
33
34 fn next<R>(self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, T, Self>
40 where
41 R: XmlReader;
42
43 fn finish<R>(self, reader: &R) -> Result<T, Error>
49 where
50 R: XmlReader;
51}
52
53pub type DeserializerResult<'a, T, B> = Result<DeserializerOutput<'a, T, B>, Error>;
55
56#[derive(Debug)]
58pub struct DeserializerOutput<'a, T, B> {
59 pub data: Option<T>,
63
64 pub deserializer: Option<B>,
67
68 pub event: Option<Event<'a>>,
70
71 pub allow_any: bool,
76}
77
78pub trait DeserializeSync<'de, R>: Sized
81where
82 R: XmlReaderSync<'de>,
83{
84 type Error;
86
87 fn deserialize(reader: &mut R) -> Result<Self, Self::Error>;
93}
94
95impl<'de, R, X> DeserializeSync<'de, R> for X
96where
97 R: XmlReaderSync<'de>,
98 X: WithDeserializer,
99{
100 type Error = Error;
101
102 fn deserialize(reader: &mut R) -> Result<Self, Self::Error> {
103 DeserializeHelper::new(reader).deserialize_sync()
104 }
105}
106
107#[cfg(feature = "async")]
110pub trait DeserializeAsync<'de, R>: Sized
111where
112 R: super::XmlReaderAsync<'de>,
113{
114 type Future<'x>: std::future::Future<Output = Result<Self, Self::Error>>
116 where
117 R: 'x,
118 'de: 'x;
119
120 type Error;
122
123 fn deserialize_async<'x>(reader: &'x mut R) -> Self::Future<'x>
125 where
126 'de: 'x;
127}
128
129#[cfg(feature = "async")]
130impl<'de, R, X> DeserializeAsync<'de, R> for X
131where
132 R: super::XmlReaderAsync<'de>,
133 X: WithDeserializer,
134{
135 type Future<'x>
136 = std::pin::Pin<Box<dyn std::future::Future<Output = Result<Self, Self::Error>> + 'x>>
137 where
138 R: 'x,
139 'de: 'x;
140
141 type Error = Error;
142
143 fn deserialize_async<'x>(reader: &'x mut R) -> Self::Future<'x>
144 where
145 'de: 'x,
146 {
147 Box::pin(async move { DeserializeHelper::new(reader).deserialize_async().await })
148 }
149}
150
151pub trait DeserializeBytes: Sized {
156 fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error>;
165}
166
167impl<X> DeserializeBytes for X
168where
169 X: FromStr,
170 X::Err: std::error::Error + Send + Sync + 'static,
171{
172 fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error> {
173 let _reader = reader;
174 let s = from_utf8(bytes).map_err(Error::from)?;
175
176 X::from_str(s).map_err(Error::custom)
177 }
178}
179
180#[derive(Debug)]
182pub struct ContentDeserializer<T> {
183 data: Vec<u8>,
184 marker: PhantomData<T>,
185}
186
187impl<'de, T> Deserializer<'de, T> for ContentDeserializer<T>
188where
189 T: DeserializeBytes + Debug,
190{
191 fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, T, Self>
192 where
193 R: XmlReader,
194 {
195 match event {
196 Event::Start(_) => Ok(DeserializerOutput {
197 data: None,
198 deserializer: Some(Self {
199 data: Vec::new(),
200 marker: PhantomData,
201 }),
202 event: None,
203 allow_any: false,
204 }),
205 Event::Empty(_) => {
206 let data = T::deserialize_bytes(reader, &[])?;
207
208 Ok(DeserializerOutput {
209 data: Some(data),
210 deserializer: None,
211 event: None,
212 allow_any: false,
213 })
214 }
215 event => Ok(DeserializerOutput {
216 data: None,
217 deserializer: None,
218 event: Some(event),
219 allow_any: false,
220 }),
221 }
222 }
223
224 fn next<R>(mut self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, T, Self>
225 where
226 R: XmlReader,
227 {
228 match event {
229 Event::Text(x) => {
230 self.data.extend_from_slice(&x.into_inner());
231
232 Ok(DeserializerOutput {
233 data: None,
234 deserializer: Some(self),
235 event: None,
236 allow_any: false,
237 })
238 }
239 Event::End(_) => {
240 let data = self.finish(reader)?;
241
242 Ok(DeserializerOutput {
243 data: Some(data),
244 deserializer: None,
245 event: None,
246 allow_any: false,
247 })
248 }
249 event => Ok(DeserializerOutput {
250 data: None,
251 deserializer: Some(self),
252 event: Some(event),
253 allow_any: false,
254 }),
255 }
256 }
257
258 fn finish<R>(self, reader: &R) -> Result<T, Error>
259 where
260 R: XmlReader,
261 {
262 T::deserialize_bytes(reader, self.data[..].trim_ascii())
263 }
264}
265
266struct DeserializeHelper<'a, 'de, T, R>
269where
270 T: WithDeserializer,
271{
272 reader: &'a mut R,
273 deserializer: Option<T::Deserializer>,
274 skip_depth: Option<usize>,
275 marker: PhantomData<&'de ()>,
276}
277
278impl<'a, 'de, T, R> DeserializeHelper<'a, 'de, T, R>
279where
280 T: WithDeserializer,
281 R: XmlReader,
282{
283 fn new(reader: &'a mut R) -> Self {
284 Self {
285 reader,
286 deserializer: None,
287 skip_depth: None,
288 marker: PhantomData,
289 }
290 }
291
292 fn handle_event(&mut self, event: Event<'_>) -> Result<Option<T>, Error> {
293 let ret = match self.deserializer.take() {
294 None => T::Deserializer::init(self.reader, event),
295 Some(b) => b.next(self.reader, event),
296 };
297
298 let DeserializerOutput {
299 data,
300 deserializer,
301 event,
302 allow_any,
303 } = ret?;
304
305 self.deserializer = deserializer;
306
307 match event {
308 None
309 | Some(
310 Event::Decl(_)
311 | Event::Text(_)
312 | Event::Comment(_)
313 | Event::DocType(_)
314 | Event::PI(_),
315 ) => (),
316 Some(event) if allow_any => {
317 if matches!(event, Event::Start(_)) {
318 self.skip_depth = Some(1);
319 }
320 }
321 Some(event) => return Err(ErrorKind::UnexpectedEvent(event.into_owned()).into()),
322 }
323
324 Ok(data)
325 }
326
327 fn handle_skip(&mut self, event: Event<'de>) -> Option<Event<'de>> {
328 let Some(skip_depth) = self.skip_depth.as_mut() else {
329 return Some(event);
330 };
331
332 match event {
333 Event::Start(_) => *skip_depth += 1,
334 Event::End(_) if *skip_depth == 1 => {
335 self.skip_depth = None;
336
337 return None;
338 }
339 Event::End(_) => *skip_depth -= 1,
340 Event::Eof => return Some(Event::Eof),
341 _ => (),
342 }
343
344 None
345 }
346}
347
348impl<'de, T, R> DeserializeHelper<'_, 'de, T, R>
349where
350 T: WithDeserializer,
351 R: XmlReaderSync<'de>,
352{
353 fn deserialize_sync(&mut self) -> Result<T, Error> {
354 loop {
355 let event = self.reader.read_event()?;
356
357 if let Some(event) = self.handle_skip(event) {
358 if let Some(data) = self
359 .handle_event(event)
360 .map_err(|error| self.reader.extend_error(error))?
361 {
362 return Ok(data);
363 }
364 }
365 }
366 }
367}
368#[cfg(feature = "async")]
369impl<'de, T, R> DeserializeHelper<'_, 'de, T, R>
370where
371 T: WithDeserializer,
372 R: super::XmlReaderAsync<'de>,
373{
374 async fn deserialize_async(&mut self) -> Result<T, Error> {
375 loop {
376 let event = self.reader.read_event_async().await?;
377
378 if let Some(event) = self.handle_skip(event) {
379 if let Some(data) = self.handle_event(event)? {
380 return Ok(data);
381 }
382 }
383 }
384 }
385}