xsd_parser/quick_xml/
error.rs

1use 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/// Quick XML Error
13#[derive(Debug)]
14pub struct Error {
15    /// Detailed information about the actual error.
16    pub kind: Kind,
17
18    /// Cursor position inside the XML document where the error occurred.
19    pub position: Option<u64>,
20
21    /// Path of XML tags where the error occurred.
22    pub elements: Option<Vec<String>>,
23}
24
25/// Quick XML error kind.
26#[derive(Debug, Error)]
27pub enum Kind {
28    /// Error forwarded from the [`quick_xml`] crate.
29    #[error("XML Error: message={0}")]
30    XmlError(#[from] XmlError),
31
32    /// Attribute error forwarded from the [`quick_xml`] crate.
33    #[error("Attribute Error: message={0}")]
34    AttrError(#[from] AttrError),
35
36    /// Invalid UTF-8 string.
37    #[error("UTF-8 Error: message={0}")]
38    InvalidUtf8(#[from] Utf8Error),
39
40    /// Duplicate attribute.
41    ///
42    /// The attribute was expected only once.
43    #[error("Duplicated attribute: name={0}")]
44    DuplicateAttribute(RawByteStr),
45
46    /// Duplicate element.
47    ///
48    /// The element was expected only once.
49    #[error("Duplicated element: name={0}")]
50    DuplicateElement(RawByteStr),
51
52    /// Unexpected attribute.
53    ///
54    /// The attribute was not expected for the current element.
55    #[error("Unexpected attribute: name={0}")]
56    UnexpectedAttribute(RawByteStr),
57
58    /// Missing attribute.
59    ///
60    /// The attribute was expected to be present, but it was not.
61    #[error("Missing attribute: name={0}")]
62    MissingAttribute(RawByteStr),
63
64    /// Missing element.
65    ///
66    /// The element was expected to be present, but it was not.
67    #[error("Missing element: name={0}")]
68    MissingElement(RawByteStr),
69
70    /// Invalid data.
71    #[error("Invalid data: `{0}`")]
72    InvalidData(RawByteStr),
73
74    /// Missing content.
75    ///
76    /// The element was expected to have some content, but it haven't.
77    #[error("Missing content")]
78    MissingContent,
79
80    /// Missing name.
81    ///
82    /// The serializer is not able to set a default name for the specified value.
83    #[error("Missing name")]
84    MissingName,
85
86    /// Unknown or invalid value.
87    #[error("Unknown or invalid value: {0}")]
88    UnknownOrInvalidValue(RawByteStr),
89
90    /// Insufficient size.
91    ///
92    /// The element or attribute contains less items then expected.
93    #[error("Insufficient size (min={min}, max={max}, actual={actual})")]
94    InsufficientSize {
95        /// Smallest expected index.
96        min: usize,
97
98        /// Largest expected index.
99        max: usize,
100
101        /// Actual index.
102        actual: usize,
103    },
104
105    /// Invalid union.
106    #[error("Invalid union: {0}")]
107    InvalidUnion(UnionError),
108
109    /// Custom error.
110    ///
111    /// Can store any kind of error.
112    #[error("Custom Error: message={0}")]
113    Custom(Box<dyn StdError + Send + Sync>),
114
115    /// Unexpected [`quick_xml`] event.
116    #[error("Unexpected event: {0:#?}!")]
117    UnexpectedEvent(Event<'static>),
118
119    /// Unexpected end of file.
120    #[error("Unexpected EoF!")]
121    UnexpectedEof,
122}
123
124impl Error {
125    /// Create a new error that uses [`Kind::Custom`] to store the passed `error`.
126    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
189/// Contains the different errors that occurred when deserializing a union.
190pub 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}