assembly_xml/common/
exact.rs1use {
3 quick_xml::{
4 events::{BytesEnd as XmlBytesEnd, BytesStart as XmlBytesStart, Event as XmlEvent},
5 Error as XmlError, Reader as XmlReader,
6 },
7 std::{error::Error as StdError, io::BufRead, str::FromStr},
8};
9
10use displaydoc::Display;
11use thiserror::Error;
12
13#[derive(Debug, Display, Error)]
15pub enum Error {
16 Xml(#[from] XmlError),
18 Generic(#[from] Box<dyn StdError + Send + Sync>),
20 ExpectedTag(String, String),
22 ExpectedEndTag(String, String),
24 MissingTag(String),
26 MissingEndTag(String),
28 MissingText,
30 MissingAttribute(String),
32 ExpectedAttribute(String, String),
34}
35
36pub type Result<T> = std::result::Result<T, Error>;
38
39pub fn expect_start<'a, 'b, 'c, B: BufRead>(
41 key: &'a str,
42 reader: &'b mut XmlReader<B>,
43 buf: &'c mut Vec<u8>,
44) -> Result<XmlBytesStart<'c>> {
45 if let Ok(XmlEvent::Start(e)) = reader.read_event(buf) {
46 if e.name() == key.as_bytes() {
47 Ok(e)
48 } else {
49 Err(Error::ExpectedTag(
50 key.to_owned(),
51 reader.decode(e.name()).into_owned(),
52 ))
53 }
54 } else {
55 Err(Error::MissingTag(key.to_owned()))
56 }
57}
58
59pub fn expect_end<'a, 'b, 'c, B: BufRead>(
61 key: &'a str,
62 reader: &'b mut XmlReader<B>,
63 buf: &'c mut Vec<u8>,
64) -> Result<XmlBytesEnd<'c>> {
65 if let Ok(XmlEvent::End(e)) = reader.read_event(buf) {
66 if e.name() == key.as_bytes() {
67 Ok(e)
68 } else {
69 Err(Error::ExpectedEndTag(
70 key.to_owned(),
71 reader.decode(e.name()).into_owned(),
72 ))
73 }
74 } else {
75 Err(Error::MissingEndTag(key.to_owned()))
76 }
77}
78
79pub fn expect_text<B: BufRead>(reader: &mut XmlReader<B>, buf: &mut Vec<u8>) -> Result<String> {
81 if let Ok(XmlEvent::Text(e)) = reader.read_event(buf) {
82 let text = e.unescape_and_decode(reader)?;
83 Ok(text)
84 } else {
85 Err(Error::MissingText)
86 }
87}
88
89pub fn expect_attribute<T: FromStr, B: BufRead>(
91 key: &str,
92 reader: &XmlReader<B>,
93 event: &XmlBytesStart,
94) -> Result<T>
95where
96 <T as FromStr>::Err: std::error::Error + Send + Sync + Sized + 'static,
97{
98 let attr = event
99 .attributes()
100 .next()
101 .ok_or_else(|| Error::MissingAttribute(key.to_owned()))??;
102
103 if attr.key == key.as_bytes() {
104 let attr_unesc = attr.unescaped_value()?;
105 let attr_str = reader.decode(&attr_unesc);
106 let value = attr_str.parse().map_err(|e| {
107 let b: Box<dyn StdError + Sync + Send> = Box::new(e);
108 b
109 })?;
110 Ok(value)
111 } else {
112 Err(Error::ExpectedAttribute(
113 key.to_owned(),
114 reader.decode(attr.key).into_owned(),
115 ))
116 }
117}