assembly_data/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 assembly_core::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>(
81 reader: &mut XmlReader<B>,
82 buf: &mut Vec<u8>,
83) -> Result<String> {
84 if let Ok(XmlEvent::Text(e)) = reader.read_event(buf) {
85 let text = e.unescape_and_decode(reader)?;
86 Ok(text)
87 } else {
88 Err(Error::MissingText)
89 }
90}
91
92pub fn expect_attribute<T: FromStr, B: BufRead>(
94 key: &str,
95 reader: &XmlReader<B>,
96 event: &XmlBytesStart,
97) -> Result<T>
98where
99 <T as FromStr>::Err: std::error::Error + Send + Sync + Sized + 'static,
100{
101 let attr = event
102 .attributes()
103 .next()
104 .ok_or_else(|| Error::MissingAttribute(key.to_owned()))??;
105
106 if attr.key == key.as_bytes() {
107 let attr_unesc = attr.unescaped_value()?;
108 let attr_str = reader.decode(&attr_unesc);
109 let value = attr_str.parse().map_err(|e| {
110 let b: Box<dyn StdError + Sync + Send> = Box::new(e);
111 b
112 })?;
113 Ok(value)
114 } else {
115 Err(Error::ExpectedAttribute(
116 key.to_owned(),
117 reader.decode(attr.key).into_owned(),
118 ))
119 }
120}