1use std::borrow::Cow;
2use std::fmt::Debug;
3use std::marker::PhantomData;
4use std::str::{from_utf8, FromStr};
5
6use quick_xml::{
7 events::{attributes::Attribute, BytesStart, Event},
8 name::{Namespace, QName, ResolveResult},
9};
10use thiserror::Error;
11
12use super::{Error, ErrorKind, RawByteStr, XmlReader, XmlReaderSync};
13
14pub trait WithDeserializer: Sized {
16 type Deserializer: for<'de> Deserializer<'de, Self>;
18}
19
20impl<X> WithDeserializer for X
21where
22 X: DeserializeBytes + Debug,
23{
24 type Deserializer = ContentDeserializer<X>;
25}
26
27pub trait Deserializer<'de, T>: Debug + Sized
30where
31 T: WithDeserializer<Deserializer = Self>,
32{
33 fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
39 where
40 R: XmlReader;
41
42 fn next<R>(self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
48 where
49 R: XmlReader;
50
51 fn finish<R>(self, reader: &R) -> Result<T, Error>
57 where
58 R: XmlReader;
59}
60
61pub type DeserializerResult<'a, T> = Result<DeserializerOutput<'a, T>, Error>;
63
64#[derive(Debug)]
66pub enum ElementHandlerOutput<'a> {
67 Continue {
69 event: Event<'a>,
71
72 allow_any: bool,
74 },
75
76 Break {
78 event: DeserializerEvent<'a>,
81
82 allow_any: bool,
84 },
85}
86
87impl<'a> ElementHandlerOutput<'a> {
88 #[must_use]
90 pub fn continue_(event: Event<'a>, allow_any: bool) -> Self {
91 Self::Continue { event, allow_any }
92 }
93
94 #[must_use]
96 pub fn break_(event: DeserializerEvent<'a>, allow_any: bool) -> Self {
97 Self::Break { event, allow_any }
98 }
99
100 #[must_use]
103 pub fn return_to_parent(event: Event<'a>, allow_any: bool) -> Self {
104 Self::break_(DeserializerEvent::Continue(event), allow_any)
105 }
106
107 #[must_use]
110 pub fn return_to_root(event: Event<'a>, allow_any: bool) -> Self {
111 Self::break_(DeserializerEvent::Break(event), allow_any)
112 }
113
114 #[must_use]
118 pub fn from_event(event: DeserializerEvent<'a>, allow_any: bool) -> Self {
119 match event {
120 DeserializerEvent::Continue(
121 event @ (Event::Start(_) | Event::Empty(_) | Event::End(_)),
122 ) => Self::continue_(event, allow_any),
123 event => Self::break_(event, allow_any),
124 }
125 }
126
127 #[must_use]
130 pub fn from_event_end(event: DeserializerEvent<'a>, allow_any: bool) -> Self {
131 match event {
132 DeserializerEvent::Continue(event @ Event::End(_)) => Self::continue_(event, allow_any),
133 DeserializerEvent::Continue(event) => {
134 Self::break_(DeserializerEvent::Break(event), allow_any)
135 }
136 event => Self::break_(event, allow_any),
137 }
138 }
139}
140
141#[derive(Debug)]
143pub struct DeserializerOutput<'a, T>
144where
145 T: WithDeserializer,
146{
147 pub artifact: DeserializerArtifact<T>,
149
150 pub event: DeserializerEvent<'a>,
152
153 pub allow_any: bool,
158}
159
160#[derive(Debug)]
164pub enum DeserializerArtifact<T>
165where
166 T: WithDeserializer,
167{
168 None,
170
171 Data(T),
174
175 Deserializer(T::Deserializer),
178}
179
180impl<T> DeserializerArtifact<T>
181where
182 T: WithDeserializer,
183{
184 pub fn is_none(&self) -> bool {
186 matches!(self, Self::None)
187 }
188
189 pub fn from_data(data: Option<T>) -> Self {
194 if let Some(data) = data {
195 Self::Data(data)
196 } else {
197 Self::None
198 }
199 }
200
201 pub fn from_deserializer(deserializer: Option<T::Deserializer>) -> Self {
206 if let Some(deserializer) = deserializer {
207 Self::Deserializer(deserializer)
208 } else {
209 Self::None
210 }
211 }
212
213 #[inline]
216 pub fn into_parts(self) -> (Option<T>, Option<T::Deserializer>) {
217 match self {
218 Self::None => (None, None),
219 Self::Data(data) => (Some(data), None),
220 Self::Deserializer(deserializer) => (None, Some(deserializer)),
221 }
222 }
223
224 #[inline]
226 pub fn map<F, G, X>(self, data_mapper: F, deserializer_mapper: G) -> DeserializerArtifact<X>
227 where
228 X: WithDeserializer,
229 F: FnOnce(T) -> X,
230 G: FnOnce(T::Deserializer) -> X::Deserializer,
231 {
232 match self {
233 Self::None => DeserializerArtifact::None,
234 Self::Data(data) => DeserializerArtifact::Data(data_mapper(data)),
235 Self::Deserializer(deserializer) => {
236 DeserializerArtifact::Deserializer(deserializer_mapper(deserializer))
237 }
238 }
239 }
240}
241
242#[derive(Debug)]
244pub enum DeserializerEvent<'a> {
245 None,
247
248 Break(Event<'a>),
251
252 Continue(Event<'a>),
255}
256
257impl<'a> DeserializerEvent<'a> {
258 #[must_use]
260 pub fn into_event(self) -> Option<Event<'a>> {
261 match self {
262 Self::None => None,
263 Self::Break(event) | Self::Continue(event) => Some(event),
264 }
265 }
266}
267
268pub trait DeserializeSync<'de, R>: Sized
271where
272 R: XmlReaderSync<'de>,
273{
274 type Error;
276
277 fn deserialize(reader: &mut R) -> Result<Self, Self::Error>;
283}
284
285impl<'de, R, X> DeserializeSync<'de, R> for X
286where
287 R: XmlReaderSync<'de>,
288 X: WithDeserializer,
289{
290 type Error = Error;
291
292 fn deserialize(reader: &mut R) -> Result<Self, Self::Error> {
293 DeserializeHelper::new(reader).deserialize_sync()
294 }
295}
296
297#[cfg(feature = "async")]
300pub trait DeserializeAsync<'de, R>: Sized
301where
302 R: super::XmlReaderAsync<'de>,
303{
304 type Future<'x>: std::future::Future<Output = Result<Self, Self::Error>>
306 where
307 R: 'x,
308 'de: 'x;
309
310 type Error;
312
313 fn deserialize_async<'x>(reader: &'x mut R) -> Self::Future<'x>
315 where
316 'de: 'x;
317}
318
319#[cfg(feature = "async")]
320impl<'de, R, X> DeserializeAsync<'de, R> for X
321where
322 R: super::XmlReaderAsync<'de>,
323 X: WithDeserializer,
324{
325 type Future<'x>
326 = std::pin::Pin<Box<dyn std::future::Future<Output = Result<Self, Self::Error>> + 'x>>
327 where
328 R: 'x,
329 'de: 'x;
330
331 type Error = Error;
332
333 fn deserialize_async<'x>(reader: &'x mut R) -> Self::Future<'x>
334 where
335 'de: 'x,
336 {
337 Box::pin(async move { DeserializeHelper::new(reader).deserialize_async().await })
338 }
339}
340
341pub trait DeserializeBytes: Sized {
346 fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error>;
355}
356
357#[derive(Debug, Error)]
360#[error("Unable to deserialize value from string (value = {value}, error = {error})")]
361pub struct DeserializeStrError<E> {
362 pub value: String,
364
365 pub error: E,
367}
368
369impl<X> DeserializeBytes for X
370where
371 X: FromStr,
372 X::Err: std::error::Error + Send + Sync + 'static,
373{
374 fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error> {
375 let _reader = reader;
376 let s = from_utf8(bytes).map_err(Error::from)?;
377
378 X::from_str(s).map_err(|error| {
379 Error::custom(DeserializeStrError {
380 value: s.into(),
381 error,
382 })
383 })
384 }
385}
386
387#[derive(Debug)]
389pub struct ContentDeserializer<T> {
390 data: Vec<u8>,
391 marker: PhantomData<T>,
392}
393
394impl<'de, T> Deserializer<'de, T> for ContentDeserializer<T>
395where
396 T: DeserializeBytes + Debug,
397{
398 fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
399 where
400 R: XmlReader,
401 {
402 match event {
403 Event::Start(_) => Ok(DeserializerOutput {
404 artifact: DeserializerArtifact::Deserializer(Self {
405 data: Vec::new(),
406 marker: PhantomData,
407 }),
408 event: DeserializerEvent::None,
409 allow_any: false,
410 }),
411 Event::Empty(_) => {
412 let data = T::deserialize_bytes(reader, &[])?;
413
414 Ok(DeserializerOutput {
415 artifact: DeserializerArtifact::Data(data),
416 event: DeserializerEvent::None,
417 allow_any: false,
418 })
419 }
420 event => Ok(DeserializerOutput {
421 artifact: DeserializerArtifact::None,
422 event: DeserializerEvent::Continue(event),
423 allow_any: false,
424 }),
425 }
426 }
427
428 fn next<R>(mut self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
429 where
430 R: XmlReader,
431 {
432 match event {
433 Event::Text(x) => {
434 self.data.extend_from_slice(&x.into_inner());
435
436 Ok(DeserializerOutput {
437 artifact: DeserializerArtifact::Deserializer(self),
438 event: DeserializerEvent::None,
439 allow_any: false,
440 })
441 }
442 Event::End(_) => {
443 let data = self.finish(reader)?;
444
445 Ok(DeserializerOutput {
446 artifact: DeserializerArtifact::Data(data),
447 event: DeserializerEvent::None,
448 allow_any: false,
449 })
450 }
451 event => Ok(DeserializerOutput {
452 artifact: DeserializerArtifact::Deserializer(self),
453 event: DeserializerEvent::Break(event),
454 allow_any: false,
455 }),
456 }
457 }
458
459 fn finish<R>(self, reader: &R) -> Result<T, Error>
460 where
461 R: XmlReader,
462 {
463 T::deserialize_bytes(reader, self.data[..].trim_ascii())
464 }
465}
466
467pub trait DeserializeReader: XmlReader {
471 fn read_attrib<T>(
478 &self,
479 store: &mut Option<T>,
480 name: &'static [u8],
481 value: &[u8],
482 ) -> Result<(), Error>
483 where
484 T: DeserializeBytes,
485 {
486 if store.is_some() {
487 self.err(ErrorKind::DuplicateAttribute(RawByteStr::from(name)))?;
488 }
489
490 let value = self.map_result(T::deserialize_bytes(self, value))?;
491 *store = Some(value);
492
493 Ok(())
494 }
495
496 fn raise_unexpected_attrib(&self, attrib: Attribute<'_>) -> Result<(), Error> {
504 self.err(ErrorKind::UnexpectedAttribute(RawByteStr::from_slice(
505 attrib.key.into_inner(),
506 )))
507 }
508
509 fn resolve_local_name<'a>(&self, name: QName<'a>, ns: &[u8]) -> Option<&'a [u8]> {
515 match self.resolve(name, true) {
516 (ResolveResult::Unbound, local) => Some(local.into_inner()),
517 (ResolveResult::Bound(x), local) if x.0 == ns => Some(local.into_inner()),
518 (_, _) => None,
519 }
520 }
521
522 fn check_start_tag_name(&self, event: &Event<'_>, ns: Option<&[u8]>, name: &[u8]) -> bool {
525 let (Event::Start(x) | Event::Empty(x)) = event else {
526 return false;
527 };
528
529 if let Some(ns) = ns {
530 matches!(self.resolve_local_name(x.name(), ns), Some(x) if x == name)
531 } else {
532 x.name().local_name().as_ref() == name
533 }
534 }
535
536 fn get_dynamic_type_name<'a>(
546 &self,
547 event: &'a Event<'_>,
548 ) -> Result<Option<Cow<'a, [u8]>>, Error> {
549 let (Event::Start(b) | Event::Empty(b)) = &event else {
550 return Ok(None);
551 };
552
553 let attrib = b
554 .attributes()
555 .find(|attrib| {
556 let Ok(attrib) = attrib else { return false };
557 let (resolve, name) = self.resolve(attrib.key, true);
558 matches!(
559 resolve,
560 ResolveResult::Unbound
561 | ResolveResult::Bound(Namespace(
562 b"http://www.w3.org/2001/XMLSchema-instance"
563 ))
564 ) && name.as_ref() == b"type"
565 })
566 .transpose()?;
567
568 let name = attrib.map_or_else(|| Cow::Borrowed(b.name().0), |attrib| attrib.value);
569
570 Ok(Some(name))
571 }
572
573 fn init_deserializer_from_start_event<'a, T, F>(
583 &self,
584 event: Event<'a>,
585 f: F,
586 ) -> Result<DeserializerOutput<'a, T>, Error>
587 where
588 T: WithDeserializer,
589 F: FnOnce(&Self, &BytesStart<'a>) -> Result<<T as WithDeserializer>::Deserializer, Error>,
590 {
591 match event {
592 Event::Start(start) => {
593 let deserializer = f(self, &start)?;
594
595 Ok(DeserializerOutput {
596 artifact: DeserializerArtifact::Deserializer(deserializer),
597 event: DeserializerEvent::None,
598 allow_any: false,
599 })
600 }
601 Event::Empty(start) => {
602 let deserializer = f(self, &start)?;
603 let data = deserializer.finish(self)?;
604
605 Ok(DeserializerOutput {
606 artifact: DeserializerArtifact::Data(data),
607 event: DeserializerEvent::None,
608 allow_any: false,
609 })
610 }
611 event => Ok(DeserializerOutput {
612 artifact: DeserializerArtifact::None,
613 event: DeserializerEvent::Continue(event),
614 allow_any: false,
615 }),
616 }
617 }
618}
619
620impl<X> DeserializeReader for X where X: XmlReader {}
621
622struct DeserializeHelper<'a, 'de, T, R>
625where
626 T: WithDeserializer,
627{
628 reader: &'a mut R,
629 deserializer: Option<T::Deserializer>,
630 skip_depth: Option<usize>,
631 marker: PhantomData<&'de ()>,
632}
633
634impl<'a, 'de, T, R> DeserializeHelper<'a, 'de, T, R>
635where
636 T: WithDeserializer,
637 R: XmlReader,
638{
639 fn new(reader: &'a mut R) -> Self {
640 Self {
641 reader,
642 deserializer: None,
643 skip_depth: None,
644 marker: PhantomData,
645 }
646 }
647
648 fn handle_event(&mut self, event: Event<'_>) -> Result<Option<T>, Error> {
649 let ret = match self.deserializer.take() {
650 None => T::Deserializer::init(self.reader, event),
651 Some(b) => b.next(self.reader, event),
652 };
653 let ret = self.reader.map_result(ret);
654
655 let DeserializerOutput {
656 artifact,
657 event,
658 allow_any,
659 } = ret?;
660
661 let (data, deserializer) = artifact.into_parts();
662
663 self.deserializer = deserializer;
664
665 match event.into_event() {
666 None
667 | Some(
668 Event::Decl(_)
669 | Event::Text(_)
670 | Event::Comment(_)
671 | Event::DocType(_)
672 | Event::PI(_),
673 ) => (),
674 Some(event) if allow_any => {
675 if matches!(event, Event::Start(_)) {
676 self.skip_depth = Some(1);
677 }
678 }
679 Some(event) => return Err(ErrorKind::UnexpectedEvent(event.into_owned()).into()),
680 }
681
682 Ok(data)
683 }
684
685 fn handle_skip(&mut self, event: Event<'de>) -> Option<Event<'de>> {
686 let Some(skip_depth) = self.skip_depth.as_mut() else {
687 return Some(event);
688 };
689
690 match event {
691 Event::Start(_) => *skip_depth += 1,
692 Event::End(_) if *skip_depth == 1 => {
693 self.skip_depth = None;
694
695 return None;
696 }
697 Event::End(_) => *skip_depth -= 1,
698 Event::Eof => return Some(Event::Eof),
699 _ => (),
700 }
701
702 None
703 }
704}
705
706impl<'de, T, R> DeserializeHelper<'_, 'de, T, R>
707where
708 T: WithDeserializer,
709 R: XmlReaderSync<'de>,
710{
711 fn deserialize_sync(&mut self) -> Result<T, Error> {
712 loop {
713 let event = self.reader.read_event()?;
714
715 if let Some(event) = self.handle_skip(event) {
716 if let Some(data) = self
717 .handle_event(event)
718 .map_err(|error| self.reader.extend_error(error))?
719 {
720 return Ok(data);
721 }
722 }
723 }
724 }
725}
726#[cfg(feature = "async")]
727impl<'de, T, R> DeserializeHelper<'_, 'de, T, R>
728where
729 T: WithDeserializer,
730 R: super::XmlReaderAsync<'de>,
731{
732 async fn deserialize_async(&mut self) -> Result<T, Error> {
733 loop {
734 let event = self.reader.read_event_async().await?;
735
736 if let Some(event) = self.handle_skip(event) {
737 if let Some(data) = self.handle_event(event)? {
738 return Ok(data);
739 }
740 }
741 }
742 }
743}