xsd_parser/quick_xml/
deserialize.rs

1use std::borrow::Cow;
2use std::fmt::Debug;
3use std::marker::PhantomData;
4use std::str::{from_utf8, FromStr};
5
6use quick_xml::{
7    escape::unescape,
8    events::{attributes::Attribute, BytesStart, BytesText, Event},
9    name::{Namespace, QName, ResolveResult},
10};
11use thiserror::Error;
12
13use super::{Error, ErrorKind, RawByteStr, XmlReader, XmlReaderSync};
14
15/// Trait that defines the [`Deserializer`] for a type.
16pub trait WithDeserializer: Sized {
17    /// The deserializer to use for this type.
18    type Deserializer: for<'de> Deserializer<'de, Self>;
19}
20
21impl<X> WithDeserializer for X
22where
23    X: DeserializeBytes + Debug,
24{
25    type Deserializer = ContentDeserializer<X>;
26}
27
28/// Trait that defines a deserializer that can be used to construct a type from a
29/// XML [`Event`]s.
30pub trait Deserializer<'de, T>: Debug + Sized
31where
32    T: WithDeserializer<Deserializer = Self>,
33{
34    /// Initializes a new deserializer from the passed `reader` and the initial `event`.
35    ///
36    /// # Errors
37    ///
38    /// Returns an [`struct@Error`] if the initialization of the deserializer failed.
39    fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
40    where
41        R: XmlReader;
42
43    /// Processes the next XML [`Event`].
44    ///
45    /// # Errors
46    ///
47    /// Returns an [`struct@Error`] if processing the event failed.
48    fn next<R>(self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
49    where
50        R: XmlReader;
51
52    /// Force the deserializer to finish.
53    ///
54    /// # Errors
55    ///
56    /// Returns an [`struct@Error`] if the deserializer could not finish.
57    fn finish<R>(self, reader: &R) -> Result<T, Error>
58    where
59        R: XmlReader;
60}
61
62/// Result type returned by the [`Deserializer`] trait.
63pub type DeserializerResult<'a, T> = Result<DeserializerOutput<'a, T>, Error>;
64
65/// Controls the flow of the deserializer
66#[derive(Debug)]
67pub enum ElementHandlerOutput<'a> {
68    /// Continue with the deserialization
69    Continue {
70        /// Event to continue the deserialization process with.
71        event: Event<'a>,
72
73        /// Wether if any element is allowed for the current deserializer.
74        allow_any: bool,
75    },
76
77    /// Break the deserialization
78    Break {
79        /// Instructions how to deal with a maybe unhandled event
80        /// returned by the child deserializer .
81        event: DeserializerEvent<'a>,
82
83        /// Wether if any element is allowed for the current deserializer.
84        allow_any: bool,
85    },
86}
87
88impl<'a> ElementHandlerOutput<'a> {
89    /// Create a [`Continue`](Self::Continue) instance.
90    #[must_use]
91    pub fn continue_(event: Event<'a>, allow_any: bool) -> Self {
92        Self::Continue { event, allow_any }
93    }
94
95    /// Create a [`Break`](Self::Break) instance.
96    #[must_use]
97    pub fn break_(event: DeserializerEvent<'a>, allow_any: bool) -> Self {
98        Self::Break { event, allow_any }
99    }
100
101    /// Create a [`Break`](Self::Break) instance that will return the passed
102    /// `event` to the parent deserializers for further processing.
103    #[must_use]
104    pub fn return_to_parent(event: Event<'a>, allow_any: bool) -> Self {
105        Self::break_(DeserializerEvent::Continue(event), allow_any)
106    }
107
108    /// Create a [`Break`](Self::Break) instance that will return the passed
109    /// `event` to root of the deserialization process.
110    #[must_use]
111    pub fn return_to_root(event: Event<'a>, allow_any: bool) -> Self {
112        Self::break_(DeserializerEvent::Break(event), allow_any)
113    }
114
115    /// Create a [`Continue`](Self::Continue) instance if the passed `event` is
116    /// a `Continue(Start)`, `Continue(Empty)`, or `Continue(End)`,
117    /// a [`Break`](Self::Break) instance otherwise.
118    #[must_use]
119    pub fn from_event(event: DeserializerEvent<'a>, allow_any: bool) -> Self {
120        match event {
121            DeserializerEvent::Continue(
122                event @ (Event::Start(_) | Event::Empty(_) | Event::End(_)),
123            ) => Self::continue_(event, allow_any),
124            event => Self::break_(event, allow_any),
125        }
126    }
127
128    /// Create a [`Continue`](Self::Continue) instance if the passed `event` is
129    /// a `Continue(End)`, a [`Break`](Self::Break) instance otherwise.
130    #[must_use]
131    pub fn from_event_end(event: DeserializerEvent<'a>, allow_any: bool) -> Self {
132        match event {
133            DeserializerEvent::Continue(event @ Event::End(_)) => Self::continue_(event, allow_any),
134            DeserializerEvent::Continue(event) => Self::return_to_parent(event, allow_any),
135            event => Self::break_(event, allow_any),
136        }
137    }
138}
139
140/// Type that is used to bundle the output of a [`Deserializer`] operation.
141#[derive(Debug)]
142pub struct DeserializerOutput<'a, T>
143where
144    T: WithDeserializer,
145{
146    /// Artifact produced by the deserializer.
147    pub artifact: DeserializerArtifact<T>,
148
149    /// Contains the processed event if it was not consumed by the deserializer.
150    pub event: DeserializerEvent<'a>,
151
152    /// Whether the deserializer allows other XML elements in the current state or not.
153    /// If this is set to `true` and the `event` is not consumed, the event should
154    /// be skipped. For [`Event::Start`] this would mean to skip the whole element
155    /// until the corresponding [`Event::End`] is received.
156    pub allow_any: bool,
157}
158
159/// Artifact that is returned by a [`Deserializer`].
160///
161/// This contains either the deserialized data or the deserializer itself.
162#[derive(Debug)]
163pub enum DeserializerArtifact<T>
164where
165    T: WithDeserializer,
166{
167    /// Is returned if the deserialization process is finished and not data was produced.
168    None,
169
170    /// Contains the actual type constructed by the deserializer, once the deserializer has
171    /// finished it's construction.
172    Data(T),
173
174    /// Contains the deserializer after an operation on the deserializer has been executed.
175    /// This will be returned if the deserialization of the type is not finished yet.
176    Deserializer(T::Deserializer),
177}
178
179impl<T> DeserializerArtifact<T>
180where
181    T: WithDeserializer,
182{
183    /// Check if this is a [`DeserializerArtifact::None`].
184    pub fn is_none(&self) -> bool {
185        matches!(self, Self::None)
186    }
187
188    /// Create a new [`DeserializerArtifact`] instance from the passed `data`.
189    ///
190    /// If `data` is `Some` a [`DeserializerArtifact::Data`] is created. If it
191    /// is a `None` a [`DeserializerArtifact::None`] is crated.
192    pub fn from_data(data: Option<T>) -> Self {
193        if let Some(data) = data {
194            Self::Data(data)
195        } else {
196            Self::None
197        }
198    }
199
200    /// Create a new [`DeserializerArtifact`] instance from the passed `deserializer`.
201    ///
202    /// If `data` is `Some` a [`DeserializerArtifact::Deserializer`] is created.
203    /// If it is a `None` a [`DeserializerArtifact::None`] is crated.
204    pub fn from_deserializer(deserializer: Option<T::Deserializer>) -> Self {
205        if let Some(deserializer) = deserializer {
206            Self::Deserializer(deserializer)
207        } else {
208            Self::None
209        }
210    }
211
212    /// Split the deserializer artifact into two options.
213    /// One for the data and one for the deserializer.
214    #[inline]
215    pub fn into_parts(self) -> (Option<T>, Option<T::Deserializer>) {
216        match self {
217            Self::None => (None, None),
218            Self::Data(data) => (Some(data), None),
219            Self::Deserializer(deserializer) => (None, Some(deserializer)),
220        }
221    }
222
223    /// Maps the data or the deserializer to new types using the passed mappers.
224    #[inline]
225    pub fn map<F, G, X>(self, data_mapper: F, deserializer_mapper: G) -> DeserializerArtifact<X>
226    where
227        X: WithDeserializer,
228        F: FnOnce(T) -> X,
229        G: FnOnce(T::Deserializer) -> X::Deserializer,
230    {
231        match self {
232            Self::None => DeserializerArtifact::None,
233            Self::Data(data) => DeserializerArtifact::Data(data_mapper(data)),
234            Self::Deserializer(deserializer) => {
235                DeserializerArtifact::Deserializer(deserializer_mapper(deserializer))
236            }
237        }
238    }
239}
240
241/// Indicates what to do with a event returned by a deserializer
242#[derive(Debug)]
243pub enum DeserializerEvent<'a> {
244    /// The event was consumed by the deserializer, nothing to handle here.
245    None,
246
247    /// The event is handled and should be returned to the deserialization root
248    /// for additional evaluation.
249    Break(Event<'a>),
250
251    /// The event was not consumed by the deserializer an may be processed again
252    /// by it's any of it's parents.
253    Continue(Event<'a>),
254}
255
256impl<'a> DeserializerEvent<'a> {
257    /// Extract the event as `Option`.
258    #[must_use]
259    pub fn into_event(self) -> Option<Event<'a>> {
260        match self {
261            Self::None => None,
262            Self::Break(event) | Self::Continue(event) => Some(event),
263        }
264    }
265}
266
267/// Trait that could be implemented by types to support deserialization from XML
268/// using the [`quick_xml`] crate.
269pub trait DeserializeSync<'de, R>: Sized
270where
271    R: XmlReaderSync<'de>,
272{
273    /// Error that is returned by the `deserialize` method.
274    type Error;
275
276    /// Deserialize the type from the passed `reader`.
277    ///
278    /// # Errors
279    ///
280    /// Will return a suitable error if the operation failed.
281    fn deserialize(reader: &mut R) -> Result<Self, Self::Error>;
282}
283
284impl<'de, R, X> DeserializeSync<'de, R> for X
285where
286    R: XmlReaderSync<'de>,
287    X: WithDeserializer,
288{
289    type Error = Error;
290
291    fn deserialize(reader: &mut R) -> Result<Self, Self::Error> {
292        DeserializeHelper::new(reader).deserialize_sync()
293    }
294}
295
296/// Trait that could be implemented by types to support asynchronous
297/// deserialization from XML using the [`quick_xml`] crate.
298#[cfg(feature = "async")]
299pub trait DeserializeAsync<'de, R>: Sized
300where
301    R: super::XmlReaderAsync<'de>,
302{
303    /// Future that is returned by the [`deserialize_async`] method.
304    type Future<'x>: std::future::Future<Output = Result<Self, Self::Error>>
305    where
306        R: 'x,
307        'de: 'x;
308
309    /// Error that is returned by the future generated by the [`deserialize_async`] method.
310    type Error;
311
312    /// Asynchronously deserializes the type from the passed `reader`.
313    fn deserialize_async<'x>(reader: &'x mut R) -> Self::Future<'x>
314    where
315        'de: 'x;
316}
317
318#[cfg(feature = "async")]
319impl<'de, R, X> DeserializeAsync<'de, R> for X
320where
321    R: super::XmlReaderAsync<'de>,
322    X: WithDeserializer,
323{
324    type Future<'x>
325        = std::pin::Pin<Box<dyn std::future::Future<Output = Result<Self, Self::Error>> + 'x>>
326    where
327        R: 'x,
328        'de: 'x;
329
330    type Error = Error;
331
332    fn deserialize_async<'x>(reader: &'x mut R) -> Self::Future<'x>
333    where
334        'de: 'x,
335    {
336        Box::pin(async move { DeserializeHelper::new(reader).deserialize_async().await })
337    }
338}
339
340/// Trait that could be implemented by types to support deserialization from
341/// XML byte streams using the [`quick_xml`] crate.
342///
343/// This is usually implemented for simple types like numbers, strings or enums.
344pub trait DeserializeBytes: Sized {
345    /// Try to deserialize the type from bytes.
346    ///
347    /// This is used to deserialize the type from attributes or raw element
348    /// content.
349    ///
350    /// # Errors
351    ///
352    /// Returns a suitable [`struct@Error`] if the deserialization was not successful.
353    fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error>;
354
355    /// Optimized version of [`deserialize_bytes`](Self::deserialize_bytes) that
356    /// takes a string instead of a bytes slice.
357    ///
358    /// This is useful if previous checks on the string already did the UTF-8 conversion.
359    ///
360    /// # Errors
361    ///
362    /// Returns a suitable [`struct@Error`] if the deserialization was not successful.
363    fn deserialize_str<R: XmlReader>(reader: &R, s: &str) -> Result<Self, Error> {
364        Self::deserialize_bytes(reader, s.as_bytes())
365    }
366}
367
368/// Error that is raised by the [`DeserializeBytes`] trait if the type implements
369/// [`FromStr`], but the conversion from the string has failed.
370#[derive(Debug, Error)]
371#[error("Unable to deserialize value from string (value = {value}, error = {error})")]
372pub struct DeserializeStrError<E> {
373    /// Value that could not be parsed.
374    pub value: String,
375
376    /// Error forwarded from [`FromStr`].
377    pub error: E,
378}
379
380impl DeserializeBytes for bool {
381    fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error> {
382        let _reader = reader;
383
384        match bytes {
385            b"TRUE" | b"True" | b"true" | b"YES" | b"Yes" | b"yes" | b"1" => Ok(true),
386            b"FALSE" | b"False" | b"false" | b"NO" | b"No" | b"no" | b"0" => Ok(false),
387            _ => Err(ErrorKind::UnknownOrInvalidValue(bytes.to_owned().into()).into()),
388        }
389    }
390}
391
392/// Marker trait used to automatically implement [`DeserializeBytes`] for any
393/// type that implements [`FromStr`].
394pub trait DeserializeBytesFromStr: FromStr {}
395
396impl<X> DeserializeBytes for X
397where
398    X: DeserializeBytesFromStr,
399    X::Err: std::error::Error + Send + Sync + 'static,
400{
401    fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error> {
402        let s = from_utf8(bytes).map_err(Error::from)?;
403
404        Self::deserialize_str(reader, s)
405    }
406
407    fn deserialize_str<R: XmlReader>(reader: &R, s: &str) -> Result<Self, Error> {
408        let _reader = reader;
409
410        X::from_str(s).map_err(|error| {
411            Error::custom(DeserializeStrError {
412                value: s.into(),
413                error,
414            })
415        })
416    }
417}
418
419impl DeserializeBytesFromStr for String {}
420
421impl DeserializeBytesFromStr for u8 {}
422impl DeserializeBytesFromStr for u16 {}
423impl DeserializeBytesFromStr for u32 {}
424impl DeserializeBytesFromStr for u64 {}
425impl DeserializeBytesFromStr for usize {}
426
427impl DeserializeBytesFromStr for i8 {}
428impl DeserializeBytesFromStr for i16 {}
429impl DeserializeBytesFromStr for i32 {}
430impl DeserializeBytesFromStr for i64 {}
431impl DeserializeBytesFromStr for isize {}
432
433impl DeserializeBytesFromStr for f32 {}
434impl DeserializeBytesFromStr for f64 {}
435
436#[cfg(feature = "num")]
437impl DeserializeBytesFromStr for num::BigInt {}
438
439#[cfg(feature = "num")]
440impl DeserializeBytesFromStr for num::BigUint {}
441
442/// Implements a [`Deserializer`] for any type that implements [`DeserializeBytes`].
443#[derive(Debug)]
444pub struct ContentDeserializer<T> {
445    data: Vec<u8>,
446    marker: PhantomData<T>,
447}
448
449impl<'de, T> Deserializer<'de, T> for ContentDeserializer<T>
450where
451    T: DeserializeBytes + Debug,
452{
453    fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
454    where
455        R: XmlReader,
456    {
457        match event {
458            Event::Start(_) => Ok(DeserializerOutput {
459                artifact: DeserializerArtifact::Deserializer(Self {
460                    data: Vec::new(),
461                    marker: PhantomData,
462                }),
463                event: DeserializerEvent::None,
464                allow_any: false,
465            }),
466            Event::Empty(_) => {
467                let data = T::deserialize_bytes(reader, &[])?;
468
469                Ok(DeserializerOutput {
470                    artifact: DeserializerArtifact::Data(data),
471                    event: DeserializerEvent::None,
472                    allow_any: false,
473                })
474            }
475            event => Ok(DeserializerOutput {
476                artifact: DeserializerArtifact::None,
477                event: DeserializerEvent::Continue(event),
478                allow_any: false,
479            }),
480        }
481    }
482
483    fn next<R>(mut self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
484    where
485        R: XmlReader,
486    {
487        match event {
488            Event::Text(x) => {
489                self.data.extend_from_slice(x.as_ref());
490
491                Ok(DeserializerOutput {
492                    artifact: DeserializerArtifact::Deserializer(self),
493                    event: DeserializerEvent::None,
494                    allow_any: false,
495                })
496            }
497            Event::GeneralRef(x) => {
498                self.data.push(b'&');
499                self.data.extend_from_slice(x.as_ref());
500                self.data.push(b';');
501
502                Ok(DeserializerOutput {
503                    artifact: DeserializerArtifact::Deserializer(self),
504                    event: DeserializerEvent::None,
505                    allow_any: false,
506                })
507            }
508            Event::End(_) => {
509                let data = self.finish(reader)?;
510
511                Ok(DeserializerOutput {
512                    artifact: DeserializerArtifact::Data(data),
513                    event: DeserializerEvent::None,
514                    allow_any: false,
515                })
516            }
517            event => Ok(DeserializerOutput {
518                artifact: DeserializerArtifact::Deserializer(self),
519                event: DeserializerEvent::Break(event),
520                allow_any: false,
521            }),
522        }
523    }
524
525    fn finish<R>(self, reader: &R) -> Result<T, Error>
526    where
527        R: XmlReader,
528    {
529        let text = from_utf8(&self.data[..])?;
530        let text = BytesText::from_escaped(text);
531        let text = text.decode()?;
532        let text = unescape(&text)?;
533
534        T::deserialize_bytes(reader, text.as_bytes().trim_ascii())
535    }
536}
537
538/* DeserializeReader */
539
540/// Reader trait with additional helper methods for deserializing.
541pub trait DeserializeReader: XmlReader {
542    /// Helper function to convert and store an attribute from the XML event.
543    ///
544    /// # Errors
545    ///
546    /// Returns an [`struct@Error`] with [`ErrorKind::DuplicateAttribute`] if `store`
547    /// already contained a value.
548    fn read_attrib<T>(
549        &self,
550        store: &mut Option<T>,
551        name: &'static [u8],
552        value: &[u8],
553    ) -> Result<(), Error>
554    where
555        T: DeserializeBytes,
556    {
557        if store.is_some() {
558            self.err(ErrorKind::DuplicateAttribute(RawByteStr::from(name)))?;
559        }
560
561        let value = self.map_result(T::deserialize_bytes(self, value))?;
562        *store = Some(value);
563
564        Ok(())
565    }
566
567    /// Raise the [`UnexpectedAttribute`](ErrorKind::UnexpectedAttribute) error
568    /// for the passed `attrib`.
569    ///
570    /// # Errors
571    ///
572    /// Will always return the [`UnexpectedAttribute`](ErrorKind::UnexpectedAttribute)
573    /// error.
574    fn raise_unexpected_attrib(&self, attrib: Attribute<'_>) -> Result<(), Error> {
575        self.err(ErrorKind::UnexpectedAttribute(RawByteStr::from_slice(
576            attrib.key.into_inner(),
577        )))
578    }
579
580    /// Raises an [`UnexpectedAttribute`](ErrorKind::UnexpectedAttribute) error
581    /// for the given attribute if it is not globally allowed (e.g., an XSI attribute).
582    ///
583    /// This method checks if the attribute is not globally allowed using
584    /// [`is_globally_allowed_attrib`](DeserializeReader::is_globally_allowed_attrib)
585    /// and, if so, raises the error. Otherwise, it returns `Ok(())`.
586    ///
587    /// # Errors
588    ///
589    /// Returns [`UnexpectedAttribute`](ErrorKind::UnexpectedAttribute) if the
590    /// attribute is not globally allowed.
591    fn raise_unexpected_attrib_checked(&self, attrib: Attribute<'_>) -> Result<(), Error> {
592        if !self.is_globally_allowed_attrib(&attrib) {
593            self.raise_unexpected_attrib(attrib)?;
594        }
595
596        Ok(())
597    }
598
599    /// Returns `true` if the given attribute is a globally allowed XML Schema
600    /// Instance (XSI) attribute, `false` otherwise.
601    ///
602    /// Specifically, this checks if the attribute is in the `xsi` namespace and
603    /// has a local name of `schemaLocation`, `noNamespaceSchemaLocation`, `type`,
604    /// or `nil`. These attributes are globally valid and do not need to be
605    /// explicitly declared in the XML schema.
606    fn is_globally_allowed_attrib(&self, attrib: &Attribute<'_>) -> bool {
607        if let (ResolveResult::Bound(x), local) = self.resolve(attrib.key, true) {
608            let local = local.as_ref();
609            x.0 == &**crate::models::schema::Namespace::XSI
610                && (local == b"schemaLocation"
611                    || local == b"noNamespaceSchemaLocation"
612                    || local == b"type"
613                    || local == b"nil")
614        } else {
615            false
616        }
617    }
618
619    /// Try to resolve the local name of the passed qname and the expected namespace.
620    ///
621    /// Checks if the passed [`QName`] `name` matches the expected namespace `ns`
622    /// and returns the local name of it. If `name` does not have a namespace prefix
623    /// to resolve, the local name is just returned as is.
624    fn resolve_local_name<'a>(&self, name: QName<'a>, ns: &[u8]) -> Option<&'a [u8]> {
625        match self.resolve(name, true) {
626            (ResolveResult::Unbound, local) => Some(local.into_inner()),
627            (ResolveResult::Bound(x), local) if x.0 == ns => Some(local.into_inner()),
628            (_, _) => None,
629        }
630    }
631
632    /// Try to extract the resolved tag name of either a [`Start`](Event::Start) or a
633    /// [`Empty`](Event::Empty) event.
634    fn check_start_tag_name(&self, event: &Event<'_>, ns: Option<&[u8]>, name: &[u8]) -> bool {
635        let (Event::Start(x) | Event::Empty(x)) = event else {
636            return false;
637        };
638
639        if let Some(ns) = ns {
640            matches!(self.resolve_local_name(x.name(), ns), Some(x) if x == name)
641        } else {
642            x.name().local_name().as_ref() == name
643        }
644    }
645
646    /// Try to initialize a deserializer for the given `event` if it is a start
647    /// or empty tag that matches the passed `ns` and `name`.
648    ///
649    /// If the event does not match the expectations, the returned `DeserializerResult`
650    /// will indicate continuation.
651    ///
652    /// # Errors
653    ///
654    /// Raises an error if the deserializer could not be initialized.
655    #[inline]
656    fn init_start_tag_deserializer<'a, T>(
657        &self,
658        event: Event<'a>,
659        ns: Option<&[u8]>,
660        name: &[u8],
661        allow_any: bool,
662    ) -> DeserializerResult<'a, T>
663    where
664        T: WithDeserializer,
665    {
666        if self.check_start_tag_name(&event, ns, name) {
667            <T as WithDeserializer>::Deserializer::init(self, event)
668        } else {
669            Ok(DeserializerOutput {
670                artifact: DeserializerArtifact::None,
671                event: DeserializerEvent::Continue(event),
672                allow_any,
673            })
674        }
675    }
676
677    /// Try to extract the type name of a dynamic type from the passed event.
678    ///
679    /// This method will try to extract the name of a dynamic type from
680    /// [`Event::Start`] or [`Event::Empty`] by either using the explicit set name
681    /// in the `type` attribute or by using the name of the xml tag.
682    ///
683    /// # Errors
684    ///
685    /// Raise an error if the attributes of the tag could not be resolved.
686    fn get_dynamic_type_name<'a>(
687        &self,
688        event: &'a Event<'_>,
689    ) -> Result<Option<Cow<'a, [u8]>>, Error> {
690        let (Event::Start(b) | Event::Empty(b)) = &event else {
691            return Ok(None);
692        };
693
694        let attrib = b
695            .attributes()
696            .find(|attrib| {
697                let Ok(attrib) = attrib else { return false };
698                let (resolve, name) = self.resolve(attrib.key, true);
699                matches!(
700                    resolve,
701                    ResolveResult::Unbound
702                        | ResolveResult::Bound(Namespace(
703                            b"http://www.w3.org/2001/XMLSchema-instance"
704                        ))
705                ) && name.as_ref() == b"type"
706            })
707            .transpose()?;
708
709        let name = attrib.map_or_else(|| Cow::Borrowed(b.name().0), |attrib| attrib.value);
710
711        Ok(Some(name))
712    }
713
714    /// Initializes a deserializer from the passed `event`.
715    ///
716    /// If the event is [`Start`](Event::Start) or [`Empty`](Event::Empty), the passed
717    /// function `f` is called with the [`BytesStart`] from the event to initialize the actual
718    /// deserializer.
719    ///
720    /// # Errors
721    ///
722    /// Forwards the errors from raised by `f`.
723    fn init_deserializer_from_start_event<'a, T, F>(
724        &self,
725        event: Event<'a>,
726        f: F,
727    ) -> Result<DeserializerOutput<'a, T>, Error>
728    where
729        T: WithDeserializer,
730        F: FnOnce(&Self, &BytesStart<'a>) -> Result<<T as WithDeserializer>::Deserializer, Error>,
731    {
732        match event {
733            Event::Start(start) => {
734                let deserializer = f(self, &start)?;
735
736                Ok(DeserializerOutput {
737                    artifact: DeserializerArtifact::Deserializer(deserializer),
738                    event: DeserializerEvent::None,
739                    allow_any: false,
740                })
741            }
742            Event::Empty(start) => {
743                let deserializer = f(self, &start)?;
744                let data = deserializer.finish(self)?;
745
746                Ok(DeserializerOutput {
747                    artifact: DeserializerArtifact::Data(data),
748                    event: DeserializerEvent::None,
749                    allow_any: false,
750                })
751            }
752            event => Ok(DeserializerOutput {
753                artifact: DeserializerArtifact::None,
754                event: DeserializerEvent::Continue(event),
755                allow_any: false,
756            }),
757        }
758    }
759}
760
761impl<X> DeserializeReader for X where X: XmlReader {}
762
763/* DeserializeHelper */
764
765struct DeserializeHelper<'a, 'de, T, R>
766where
767    T: WithDeserializer,
768{
769    reader: &'a mut R,
770    deserializer: Option<T::Deserializer>,
771    skip_depth: Option<usize>,
772    marker: PhantomData<&'de ()>,
773}
774
775impl<'a, 'de, T, R> DeserializeHelper<'a, 'de, T, R>
776where
777    T: WithDeserializer,
778    R: XmlReader,
779{
780    fn new(reader: &'a mut R) -> Self {
781        Self {
782            reader,
783            deserializer: None,
784            skip_depth: None,
785            marker: PhantomData,
786        }
787    }
788
789    fn handle_event(&mut self, event: Event<'_>) -> Result<Option<T>, Error> {
790        let ret = match self.deserializer.take() {
791            None => T::Deserializer::init(self.reader, event),
792            Some(b) => b.next(self.reader, event),
793        };
794        let ret = self.reader.map_result(ret);
795
796        let DeserializerOutput {
797            artifact,
798            event,
799            allow_any,
800        } = ret?;
801
802        let (data, deserializer) = artifact.into_parts();
803
804        self.deserializer = deserializer;
805
806        match event.into_event() {
807            None
808            | Some(
809                Event::Decl(_)
810                | Event::Text(_)
811                | Event::Comment(_)
812                | Event::DocType(_)
813                | Event::GeneralRef(_)
814                | Event::PI(_),
815            ) => (),
816            Some(event) if allow_any => {
817                if matches!(event, Event::Start(_)) {
818                    self.skip_depth = Some(1);
819                }
820            }
821            Some(event) => return Err(ErrorKind::UnexpectedEvent(event.into_owned()).into()),
822        }
823
824        Ok(data)
825    }
826
827    fn handle_skip(&mut self, event: Event<'de>) -> Option<Event<'de>> {
828        let Some(skip_depth) = self.skip_depth.as_mut() else {
829            return Some(event);
830        };
831
832        match event {
833            Event::Start(_) => *skip_depth += 1,
834            Event::End(_) if *skip_depth == 1 => {
835                self.skip_depth = None;
836
837                return None;
838            }
839            Event::End(_) => *skip_depth -= 1,
840            Event::Eof => return Some(Event::Eof),
841            _ => (),
842        }
843
844        None
845    }
846}
847
848impl<'de, T, R> DeserializeHelper<'_, 'de, T, R>
849where
850    T: WithDeserializer,
851    R: XmlReaderSync<'de>,
852{
853    fn deserialize_sync(&mut self) -> Result<T, Error> {
854        loop {
855            let event = self.reader.read_event()?;
856
857            if let Some(event) = self.handle_skip(event) {
858                if let Some(data) = self
859                    .handle_event(event)
860                    .map_err(|error| self.reader.extend_error(error))?
861                {
862                    return Ok(data);
863                }
864            }
865        }
866    }
867}
868#[cfg(feature = "async")]
869impl<'de, T, R> DeserializeHelper<'_, 'de, T, R>
870where
871    T: WithDeserializer,
872    R: super::XmlReaderAsync<'de>,
873{
874    async fn deserialize_async(&mut self) -> Result<T, Error> {
875        loop {
876            let event = self.reader.read_event_async().await?;
877
878            if let Some(event) = self.handle_skip(event) {
879                if let Some(data) = self.handle_event(event)? {
880                    return Ok(data);
881                }
882            }
883        }
884    }
885}