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
15pub trait WithDeserializer: Sized {
17    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
28pub trait Deserializer<'de, T>: Debug + Sized
31where
32    T: WithDeserializer<Deserializer = Self>,
33{
34    fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
40    where
41        R: XmlReader;
42
43    fn next<R>(self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, T>
49    where
50        R: XmlReader;
51
52    fn finish<R>(self, reader: &R) -> Result<T, Error>
58    where
59        R: XmlReader;
60}
61
62pub type DeserializerResult<'a, T> = Result<DeserializerOutput<'a, T>, Error>;
64
65#[derive(Debug)]
67pub enum ElementHandlerOutput<'a> {
68    Continue {
70        event: Event<'a>,
72
73        allow_any: bool,
75    },
76
77    Break {
79        event: DeserializerEvent<'a>,
82
83        allow_any: bool,
85    },
86}
87
88impl<'a> ElementHandlerOutput<'a> {
89    #[must_use]
91    pub fn continue_(event: Event<'a>, allow_any: bool) -> Self {
92        Self::Continue { event, allow_any }
93    }
94
95    #[must_use]
97    pub fn break_(event: DeserializerEvent<'a>, allow_any: bool) -> Self {
98        Self::Break { event, allow_any }
99    }
100
101    #[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    #[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    #[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    #[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#[derive(Debug)]
142pub struct DeserializerOutput<'a, T>
143where
144    T: WithDeserializer,
145{
146    pub artifact: DeserializerArtifact<T>,
148
149    pub event: DeserializerEvent<'a>,
151
152    pub allow_any: bool,
157}
158
159#[derive(Debug)]
163pub enum DeserializerArtifact<T>
164where
165    T: WithDeserializer,
166{
167    None,
169
170    Data(T),
173
174    Deserializer(T::Deserializer),
177}
178
179impl<T> DeserializerArtifact<T>
180where
181    T: WithDeserializer,
182{
183    pub fn is_none(&self) -> bool {
185        matches!(self, Self::None)
186    }
187
188    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    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    #[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    #[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#[derive(Debug)]
243pub enum DeserializerEvent<'a> {
244    None,
246
247    Break(Event<'a>),
250
251    Continue(Event<'a>),
254}
255
256impl<'a> DeserializerEvent<'a> {
257    #[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
267pub trait DeserializeSync<'de, R>: Sized
270where
271    R: XmlReaderSync<'de>,
272{
273    type Error;
275
276    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#[cfg(feature = "async")]
299pub trait DeserializeAsync<'de, R>: Sized
300where
301    R: super::XmlReaderAsync<'de>,
302{
303    type Future<'x>: std::future::Future<Output = Result<Self, Self::Error>>
305    where
306        R: 'x,
307        'de: 'x;
308
309    type Error;
311
312    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
340pub trait DeserializeBytes: Sized {
345    fn deserialize_bytes<R: XmlReader>(reader: &R, bytes: &[u8]) -> Result<Self, Error>;
354
355    fn deserialize_str<R: XmlReader>(reader: &R, s: &str) -> Result<Self, Error> {
364        Self::deserialize_bytes(reader, s.as_bytes())
365    }
366}
367
368#[derive(Debug, Error)]
371#[error("Unable to deserialize value from string (value = {value}, error = {error})")]
372pub struct DeserializeStrError<E> {
373    pub value: String,
375
376    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
392pub 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#[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
538pub trait DeserializeReader: XmlReader {
542    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    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    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    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    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    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    #[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    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    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
763struct 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}