1use std::error::Error as StdError;
2use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
3use std::io::Error as IoError;
4use std::mem::take;
5use std::str::Utf8Error;
6
7use quick_xml::{
8 encoding::EncodingError,
9 escape::EscapeError,
10 events::{attributes::AttrError, Event},
11 Error as XmlError,
12};
13use thiserror::Error;
14
15use crate::models::RawByteStr;
16
17#[derive(Debug)]
19pub struct Error {
20 pub kind: Kind,
22
23 pub position: Option<u64>,
25
26 pub elements: Option<Vec<String>>,
28}
29
30#[derive(Debug, Error)]
32pub enum Kind {
33 #[error("IO Error: message={0}")]
35 IoError(
36 #[from]
37 #[source]
38 IoError,
39 ),
40
41 #[error("XML Error: message={0}")]
43 XmlError(
44 #[from]
45 #[source]
46 XmlError,
47 ),
48
49 #[error("Attribute Error: message={0}")]
51 AttrError(
52 #[from]
53 #[source]
54 AttrError,
55 ),
56
57 #[error("UTF-8 Error: message={0}")]
59 InvalidUtf8(
60 #[from]
61 #[source]
62 Utf8Error,
63 ),
64
65 #[error("Escape Error: message={0}")]
67 EscapeError(
68 #[from]
69 #[source]
70 EscapeError,
71 ),
72
73 #[error("Encoding Error: message={0}")]
75 EncodingError(
76 #[from]
77 #[source]
78 EncodingError,
79 ),
80
81 #[error("Duplicated attribute: name={0}")]
85 DuplicateAttribute(RawByteStr),
86
87 #[error("Duplicated element: name={0}")]
91 DuplicateElement(RawByteStr),
92
93 #[error("Unexpected attribute: name={0}")]
97 UnexpectedAttribute(RawByteStr),
98
99 #[error("Missing attribute: name={0}")]
103 MissingAttribute(RawByteStr),
104
105 #[error("Missing element: name={0}")]
109 MissingElement(RawByteStr),
110
111 #[error("Invalid data: `{0}`")]
113 InvalidData(RawByteStr),
114
115 #[error("Invalid value `{0}`: {1}")]
117 InvalidValue(RawByteStr, ValidateError),
118
119 #[error("Missing content")]
123 MissingContent,
124
125 #[error("Duplicate content")]
129 DuplicateContent,
130
131 #[error("Missing any element")]
135 MissingAnyElement,
136
137 #[error("Duplicate any element")]
141 DuplicateAnyElement,
142
143 #[error("Missing name")]
147 MissingName,
148
149 #[error("Unknown or invalid value: {0}")]
151 UnknownOrInvalidValue(RawByteStr),
152
153 #[error("Insufficient size (min={min}, max={max}, actual={actual})")]
157 InsufficientSize {
158 min: usize,
160
161 max: usize,
163
164 actual: usize,
166 },
167
168 #[error("Invalid union: {0}")]
170 InvalidUnion(UnionError),
171
172 #[error("Custom Error: message={0}")]
176 Custom(Box<dyn StdError + Send + Sync>),
177
178 #[error("Unexpected event: {0:#?}!")]
180 UnexpectedEvent(Event<'static>),
181
182 #[error("Unexpected EoF!")]
184 UnexpectedEof,
185}
186
187#[derive(Debug, Error)]
189pub enum ValidateError {
190 #[error("Value is not a valid decimal!")]
192 InvalidDecimalValue,
193
194 #[error("Value is shorter then {0} characters!")]
196 MinLength(usize),
197
198 #[error("Value is longer than {0} characters!")]
200 MaxLength(usize),
201
202 #[error("Value does not match the expected pattern `{0}`!")]
204 Pattern(&'static str),
205
206 #[error("Value has more then {0} total digits!")]
208 TotalDigits(usize),
209
210 #[error("Value has more then {0} fraction digits!")]
212 FractionDigits(usize),
213
214 #[error("Value is less then `{0}`!")]
218 LessThan(&'static str),
219
220 #[error("Value is less or equal then `{0}`!")]
224 LessEqualThan(&'static str),
225
226 #[error("Value is greater then `{0}`!")]
230 GraterThan(&'static str),
231
232 #[error("Value is greater equal then `{0}`!")]
236 GraterEqualThan(&'static str),
237}
238
239impl Error {
240 pub fn custom<E: StdError + Send + Sync + 'static>(error: E) -> Self {
242 Kind::Custom(Box::new(error)).into()
243 }
244
245 pub(super) fn new<E>(error: E) -> Self
246 where
247 Kind: From<E>,
248 {
249 Self {
250 kind: Kind::from(error),
251 position: None,
252 elements: None,
253 }
254 }
255
256 pub(super) fn with_pos(mut self, position: u64) -> Self {
257 self.position = Some(position);
258
259 self
260 }
261
262 pub(super) fn with_error_info(mut self, info: &ErrorInfo) -> Self {
263 self.elements = Some(info.elements.clone());
264
265 self
266 }
267}
268
269impl<E> From<E> for Error
270where
271 Kind: From<E>,
272{
273 fn from(error: E) -> Self {
274 Self::new(error)
275 }
276}
277
278impl<'a> From<(&'a [u8], ValidateError)> for Error {
279 fn from((value, error): (&'a [u8], ValidateError)) -> Self {
280 Self::new(Kind::InvalidValue(RawByteStr::from_slice(value), error))
281 }
282}
283
284impl Display for Error {
285 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
286 write!(f, "{}", &self.kind)?;
287
288 if let Some(pos) = &self.position {
289 write!(f, "; position={}", pos)?;
290 }
291
292 if let Some(elements) = &self.elements {
293 let mut first = true;
294
295 for element in elements {
296 if take(&mut first) {
297 write!(f, "; element={}", element)?;
298 } else {
299 write!(f, ">{}", element)?;
300 }
301 }
302 }
303
304 Ok(())
305 }
306}
307
308impl StdError for Error {}
309
310pub struct UnionError(Vec<Box<dyn StdError + Send + Sync + 'static>>);
312
313impl<X> From<X> for UnionError
314where
315 X: IntoIterator,
316 X::Item: StdError + Send + Sync + 'static,
317{
318 fn from(value: X) -> Self {
319 Self(
320 value
321 .into_iter()
322 .map(|err| -> Box<dyn StdError + Send + Sync + 'static> { Box::new(err) })
323 .collect(),
324 )
325 }
326}
327
328impl Debug for UnionError {
329 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
330 for err in &self.0 {
331 write!(f, "- {err}")?;
332 }
333
334 Ok(())
335 }
336}
337
338impl Display for UnionError {
339 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
340 for err in &self.0 {
341 write!(f, "- {err}")?;
342 }
343
344 Ok(())
345 }
346}
347
348#[derive(Default, Debug)]
349pub(super) struct ErrorInfo {
350 elements: Vec<String>,
351}
352
353impl ErrorInfo {
354 pub(super) fn update(&mut self, event: &Event<'_>) {
355 match event {
356 Event::Start(x) => {
357 self.elements
358 .push(String::from_utf8_lossy(x.name().0).to_string());
359 }
360 Event::End(_) => {
361 self.elements.pop();
362 }
363 _ => (),
364 }
365 }
366}