1use quick_xml::events::{BytesStart, Event};
2use quick_xml::name::ResolveResult;
3use std::io::BufRead;
4pub use xml_derive::XmlDeserialize;
5pub use xml_derive::XmlDocument;
6
7use crate::XmlError;
8use crate::XmlRootTag;
9
10pub trait XmlDeserialize: Sized {
11 fn deserialize<R: BufRead>(
12 reader: &mut quick_xml::NsReader<R>,
13 start: &BytesStart,
14 empty: bool,
15 ) -> Result<Self, XmlError>;
16}
17
18pub trait XmlDocument: XmlDeserialize {
19 fn parse<R: BufRead>(reader: quick_xml::NsReader<R>) -> Result<Self, XmlError>;
20
21 #[inline]
22 fn parse_reader<R: BufRead>(input: R) -> Result<Self, XmlError>
23 where
24 Self: XmlDeserialize,
25 {
26 let mut reader = quick_xml::NsReader::from_reader(input);
27 reader.config_mut().trim_text(true);
28 Self::parse(reader)
29 }
30
31 #[inline]
32 fn parse_str(s: &str) -> Result<Self, XmlError> {
33 Self::parse_reader(s.as_bytes())
34 }
35}
36
37impl<T: XmlRootTag + XmlDeserialize> XmlDocument for T {
38 fn parse<R: BufRead>(mut reader: quick_xml::NsReader<R>) -> Result<Self, XmlError>
39 where
40 Self: XmlDeserialize,
41 {
42 let mut buf = Vec::new();
43 loop {
44 let event = reader.read_event_into(&mut buf)?;
45 let empty = matches!(event, Event::Empty(_));
46 match event {
47 Event::Decl(_) => { }
48 Event::Comment(_) => { }
49 Event::Start(start) | Event::Empty(start) => {
50 let (ns, name) = reader.resolve_element(start.name());
51 let matches = match (Self::root_ns(), &ns, name) {
52 (_, _, name) if name.as_ref() != Self::root_tag() => false,
54 (Some(root_ns), ns, _) if &ResolveResult::Bound(root_ns) != ns => false,
56 _ => true,
57 };
58 if !matches {
59 let root_ns = Self::root_ns();
60 return Err(XmlError::InvalidTag(
61 format!("{ns:?}"),
62 String::from_utf8_lossy(name.as_ref()).to_string(),
63 format!("{root_ns:?}"),
64 String::from_utf8_lossy(Self::root_tag()).to_string(),
65 ));
66 };
67
68 return Self::deserialize(&mut reader, &start, empty);
69 }
70 Event::Eof => return Err(XmlError::Eof),
71 _ => return Err(XmlError::UnsupportedEvent("unknown, todo")),
72 };
73 }
74 }
75}
76
77impl XmlDeserialize for () {
78 fn deserialize<R: BufRead>(
79 reader: &mut quick_xml::NsReader<R>,
80 start: &BytesStart,
81 empty: bool,
82 ) -> Result<Self, XmlError> {
83 if empty {
84 return Ok(());
85 }
86 let mut buf = Vec::new();
87 loop {
88 match reader.read_event_into(&mut buf)? {
89 Event::End(e) if e.name() == start.name() => return Ok(()),
90 Event::Eof => return Err(XmlError::Eof),
91 _ => {}
92 };
93 }
94 }
95}