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}