xsd_parser/quick_xml/
error.rs1use std::error::Error as StdError;
2use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
3use std::mem::take;
4use std::str::Utf8Error;
5
6use quick_xml::events::attributes::AttrError;
7use quick_xml::{events::Event, Error as XmlError};
8use thiserror::Error;
9
10use crate::misc::RawByteStr;
11
12#[derive(Debug)]
14pub struct Error {
15 pub kind: Kind,
17
18 pub position: Option<u64>,
20
21 pub elements: Option<Vec<String>>,
23}
24
25#[derive(Debug, Error)]
27pub enum Kind {
28 #[error("XML Error: message={0}")]
30 XmlError(#[from] XmlError),
31
32 #[error("Attribute Error: message={0}")]
34 AttrError(#[from] AttrError),
35
36 #[error("UTF-8 Error: message={0}")]
38 InvalidUtf8(#[from] Utf8Error),
39
40 #[error("Duplicated attribute: name={0}")]
44 DuplicateAttribute(RawByteStr),
45
46 #[error("Duplicated element: name={0}")]
50 DuplicateElement(RawByteStr),
51
52 #[error("Unexpected attribute: name={0}")]
56 UnexpectedAttribute(RawByteStr),
57
58 #[error("Missing attribute: name={0}")]
62 MissingAttribute(RawByteStr),
63
64 #[error("Missing element: name={0}")]
68 MissingElement(RawByteStr),
69
70 #[error("Invalid data: `{0}`")]
72 InvalidData(RawByteStr),
73
74 #[error("Missing content")]
78 MissingContent,
79
80 #[error("Missing name")]
84 MissingName,
85
86 #[error("Unknown or invalid value: {0}")]
88 UnknownOrInvalidValue(RawByteStr),
89
90 #[error("Insufficient size (min={min}, max={max}, actual={actual})")]
94 InsufficientSize {
95 min: usize,
97
98 max: usize,
100
101 actual: usize,
103 },
104
105 #[error("Invalid union: {0}")]
107 InvalidUnion(UnionError),
108
109 #[error("Custom Error: message={0}")]
113 Custom(Box<dyn StdError + Send + Sync>),
114
115 #[error("Unexpected event: {0:#?}!")]
117 UnexpectedEvent(Event<'static>),
118
119 #[error("Unexpected EoF!")]
121 UnexpectedEof,
122}
123
124impl Error {
125 pub fn custom<E: StdError + Send + Sync + 'static>(error: E) -> Self {
127 Kind::Custom(Box::new(error)).into()
128 }
129
130 pub(super) fn new<E>(error: E) -> Self
131 where
132 Kind: From<E>,
133 {
134 Self {
135 kind: Kind::from(error),
136 position: None,
137 elements: None,
138 }
139 }
140
141 pub(super) fn with_pos(mut self, position: u64) -> Self {
142 self.position = Some(position);
143
144 self
145 }
146
147 pub(super) fn with_error_info(mut self, info: &ErrorInfo) -> Self {
148 self.elements = Some(info.elements.clone());
149
150 self
151 }
152}
153
154impl<E> From<E> for Error
155where
156 Kind: From<E>,
157{
158 fn from(error: E) -> Self {
159 Self::new(error)
160 }
161}
162
163impl Display for Error {
164 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
165 write!(f, "{}", &self.kind)?;
166
167 if let Some(pos) = &self.position {
168 write!(f, "; position={}", pos)?;
169 }
170
171 if let Some(elements) = &self.elements {
172 let mut first = true;
173
174 for element in elements {
175 if take(&mut first) {
176 write!(f, "; element={}", element)?;
177 } else {
178 write!(f, ">{}", element)?;
179 }
180 }
181 }
182
183 Ok(())
184 }
185}
186
187impl StdError for Error {}
188
189pub struct UnionError(Vec<Box<dyn StdError + Send + Sync + 'static>>);
191
192impl<X> From<X> for UnionError
193where
194 X: IntoIterator,
195 X::Item: StdError + Send + Sync + 'static,
196{
197 fn from(value: X) -> Self {
198 Self(
199 value
200 .into_iter()
201 .map(|err| -> Box<dyn StdError + Send + Sync + 'static> { Box::new(err) })
202 .collect(),
203 )
204 }
205}
206
207impl Debug for UnionError {
208 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
209 for err in &self.0 {
210 write!(f, "- {err}")?;
211 }
212
213 Ok(())
214 }
215}
216
217impl Display for UnionError {
218 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
219 for err in &self.0 {
220 write!(f, "- {err}")?;
221 }
222
223 Ok(())
224 }
225}
226
227#[derive(Default, Debug)]
228pub(super) struct ErrorInfo {
229 elements: Vec<String>,
230}
231
232impl ErrorInfo {
233 pub(super) fn update(&mut self, event: &Event<'_>) {
234 match event {
235 Event::Start(x) => {
236 self.elements
237 .push(String::from_utf8_lossy(x.name().0).to_string());
238 }
239 Event::End(_) => {
240 self.elements.pop();
241 }
242 _ => (),
243 }
244 }
245}