/rust/registry/src/index.crates.io-1949cf8c6b5b557f/quick-xml-0.29.0/src/errors.rs
Line | Count | Source |
1 | | //! Error management module |
2 | | |
3 | | use crate::escape::EscapeError; |
4 | | use crate::events::attributes::AttrError; |
5 | | use crate::utils::write_byte_string; |
6 | | use std::fmt; |
7 | | use std::io::Error as IoError; |
8 | | use std::str::Utf8Error; |
9 | | use std::string::FromUtf8Error; |
10 | | use std::sync::Arc; |
11 | | |
12 | | /// The error type used by this crate. |
13 | | #[derive(Clone, Debug)] |
14 | | pub enum Error { |
15 | | /// IO error. |
16 | | /// |
17 | | /// `Arc<IoError>` instead of `IoError` since `IoError` is not `Clone`. |
18 | | Io(Arc<IoError>), |
19 | | /// Input decoding error. If `encoding` feature is disabled, contains `None`, |
20 | | /// otherwise contains the UTF-8 decoding error |
21 | | NonDecodable(Option<Utf8Error>), |
22 | | /// Unexpected End of File |
23 | | UnexpectedEof(String), |
24 | | /// End event mismatch |
25 | | EndEventMismatch { |
26 | | /// Expected end event |
27 | | expected: String, |
28 | | /// Found end event |
29 | | found: String, |
30 | | }, |
31 | | /// Unexpected token |
32 | | UnexpectedToken(String), |
33 | | /// Unexpected <!> |
34 | | UnexpectedBang(u8), |
35 | | /// Text not found, expected `Event::Text` |
36 | | TextNotFound, |
37 | | /// `Event::BytesDecl` must start with *version* attribute. Contains the attribute |
38 | | /// that was found or `None` if an xml declaration doesn't contain attributes. |
39 | | XmlDeclWithoutVersion(Option<String>), |
40 | | /// Empty `Event::DocType`. `<!doctype foo>` is correct but `<!doctype > is not. |
41 | | /// |
42 | | /// See <https://www.w3.org/TR/xml11/#NT-doctypedecl> |
43 | | EmptyDocType, |
44 | | /// Attribute parsing error |
45 | | InvalidAttr(AttrError), |
46 | | /// Escape error |
47 | | EscapeError(EscapeError), |
48 | | /// Specified namespace prefix is unknown, cannot resolve namespace for it |
49 | | UnknownPrefix(Vec<u8>), |
50 | | } |
51 | | |
52 | | impl From<IoError> for Error { |
53 | | /// Creates a new `Error::Io` from the given error |
54 | | #[inline] |
55 | 0 | fn from(error: IoError) -> Error { |
56 | 0 | Error::Io(Arc::new(error)) |
57 | 0 | } |
58 | | } |
59 | | |
60 | | impl From<Utf8Error> for Error { |
61 | | /// Creates a new `Error::NonDecodable` from the given error |
62 | | #[inline] |
63 | 0 | fn from(error: Utf8Error) -> Error { |
64 | 0 | Error::NonDecodable(Some(error)) |
65 | 0 | } |
66 | | } |
67 | | |
68 | | impl From<FromUtf8Error> for Error { |
69 | | /// Creates a new `Error::Utf8` from the given error |
70 | | #[inline] |
71 | 0 | fn from(error: FromUtf8Error) -> Error { |
72 | 0 | error.utf8_error().into() |
73 | 0 | } |
74 | | } |
75 | | |
76 | | impl From<EscapeError> for Error { |
77 | | /// Creates a new `Error::EscapeError` from the given error |
78 | | #[inline] |
79 | 0 | fn from(error: EscapeError) -> Error { |
80 | 0 | Error::EscapeError(error) |
81 | 0 | } |
82 | | } |
83 | | |
84 | | impl From<AttrError> for Error { |
85 | | #[inline] |
86 | 0 | fn from(error: AttrError) -> Self { |
87 | 0 | Error::InvalidAttr(error) |
88 | 0 | } |
89 | | } |
90 | | |
91 | | /// A specialized `Result` type where the error is hard-wired to [`Error`]. |
92 | | pub type Result<T> = std::result::Result<T, Error>; |
93 | | |
94 | | impl fmt::Display for Error { |
95 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
96 | 0 | match self { |
97 | 0 | Error::Io(e) => write!(f, "I/O error: {}", e), |
98 | 0 | Error::NonDecodable(None) => write!(f, "Malformed input, decoding impossible"), |
99 | 0 | Error::NonDecodable(Some(e)) => write!(f, "Malformed UTF-8 input: {}", e), |
100 | 0 | Error::UnexpectedEof(e) => write!(f, "Unexpected EOF during reading {}", e), |
101 | 0 | Error::EndEventMismatch { expected, found } => { |
102 | 0 | write!(f, "Expecting </{}> found </{}>", expected, found) |
103 | | } |
104 | 0 | Error::UnexpectedToken(e) => write!(f, "Unexpected token '{}'", e), |
105 | 0 | Error::UnexpectedBang(b) => write!( |
106 | 0 | f, |
107 | 0 | "Only Comment (`--`), CDATA (`[CDATA[`) and DOCTYPE (`DOCTYPE`) nodes can start with a '!', but symbol `{}` found", |
108 | 0 | *b as char |
109 | | ), |
110 | 0 | Error::TextNotFound => write!(f, "Cannot read text, expecting Event::Text"), |
111 | 0 | Error::XmlDeclWithoutVersion(e) => write!( |
112 | 0 | f, |
113 | 0 | "XmlDecl must start with 'version' attribute, found {:?}", |
114 | | e |
115 | | ), |
116 | 0 | Error::EmptyDocType => write!(f, "DOCTYPE declaration must not be empty"), |
117 | 0 | Error::InvalidAttr(e) => write!(f, "error while parsing attribute: {}", e), |
118 | 0 | Error::EscapeError(e) => write!(f, "{}", e), |
119 | 0 | Error::UnknownPrefix(prefix) => { |
120 | 0 | f.write_str("Unknown namespace prefix '")?; |
121 | 0 | write_byte_string(f, prefix)?; |
122 | 0 | f.write_str("'") |
123 | | } |
124 | | } |
125 | 0 | } |
126 | | } |
127 | | |
128 | | impl std::error::Error for Error { |
129 | 0 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { |
130 | 0 | match self { |
131 | 0 | Error::Io(e) => Some(e), |
132 | 0 | Error::NonDecodable(Some(e)) => Some(e), |
133 | 0 | Error::InvalidAttr(e) => Some(e), |
134 | 0 | Error::EscapeError(e) => Some(e), |
135 | 0 | _ => None, |
136 | | } |
137 | 0 | } |
138 | | } |
139 | | |
140 | | #[cfg(feature = "serialize")] |
141 | | pub mod serialize { |
142 | | //! A module to handle serde (de)serialization errors |
143 | | |
144 | | use super::*; |
145 | | use crate::utils::write_byte_string; |
146 | | use std::borrow::Cow; |
147 | | #[cfg(feature = "overlapped-lists")] |
148 | | use std::num::NonZeroUsize; |
149 | | use std::num::{ParseFloatError, ParseIntError}; |
150 | | |
151 | | /// (De)serialization error |
152 | | #[derive(Clone, Debug)] |
153 | | pub enum DeError { |
154 | | /// Serde custom error |
155 | | Custom(String), |
156 | | /// Xml parsing error |
157 | | InvalidXml(Error), |
158 | | /// Cannot parse to integer |
159 | | InvalidInt(ParseIntError), |
160 | | /// Cannot parse to float |
161 | | InvalidFloat(ParseFloatError), |
162 | | /// Cannot parse specified value to boolean |
163 | | InvalidBoolean(String), |
164 | | /// This error indicates an error in the [`Deserialize`](serde::Deserialize) |
165 | | /// implementation when read a map or a struct: `MapAccess::next_value[_seed]` |
166 | | /// was called before `MapAccess::next_key[_seed]`. |
167 | | /// |
168 | | /// You should check your types, that implements corresponding trait. |
169 | | KeyNotRead, |
170 | | /// Deserializer encounter a start tag with a specified name when it is |
171 | | /// not expecting. This happens when you try to deserialize a primitive |
172 | | /// value (numbers, strings, booleans) from an XML element. |
173 | | UnexpectedStart(Vec<u8>), |
174 | | /// Deserializer encounter an end tag with a specified name when it is |
175 | | /// not expecting. Usually that should not be possible, because XML reader |
176 | | /// is not able to produce such stream of events that lead to this error. |
177 | | /// |
178 | | /// If you get this error this likely indicates and error in the `quick_xml`. |
179 | | /// Please open an issue at <https://github.com/tafia/quick-xml>, provide |
180 | | /// your Rust code and XML input. |
181 | | UnexpectedEnd(Vec<u8>), |
182 | | /// The [`Reader`] produced [`Event::Eof`] when it is not expecting, |
183 | | /// for example, after producing [`Event::Start`] but before corresponding |
184 | | /// [`Event::End`]. |
185 | | /// |
186 | | /// [`Reader`]: crate::reader::Reader |
187 | | /// [`Event::Eof`]: crate::events::Event::Eof |
188 | | /// [`Event::Start`]: crate::events::Event::Start |
189 | | /// [`Event::End`]: crate::events::Event::End |
190 | | UnexpectedEof, |
191 | | /// This error indicates that [`deserialize_struct`] was called, but there |
192 | | /// is no any XML element in the input. That means that you try to deserialize |
193 | | /// a struct not from an XML element. |
194 | | /// |
195 | | /// [`deserialize_struct`]: serde::de::Deserializer::deserialize_struct |
196 | | ExpectedStart, |
197 | | /// An attempt to deserialize to a type, that is not supported by the XML |
198 | | /// store at current position, for example, attempt to deserialize `struct` |
199 | | /// from attribute or attempt to deserialize binary data. |
200 | | /// |
201 | | /// Serialized type cannot be represented in an XML due to violation of the |
202 | | /// XML rules in the final XML document. For example, attempt to serialize |
203 | | /// a `HashMap<{integer}, ...>` would cause this error because [XML name] |
204 | | /// cannot start from a digit or a hyphen (minus sign). The same result |
205 | | /// would occur if map key is a complex type that cannot be serialized as |
206 | | /// a primitive type (i.e. string, char, bool, unit struct or unit variant). |
207 | | /// |
208 | | /// [XML name]: https://www.w3.org/TR/xml11/#sec-common-syn |
209 | | Unsupported(Cow<'static, str>), |
210 | | /// Too many events were skipped while deserializing a sequence, event limit |
211 | | /// exceeded. The limit was provided as an argument |
212 | | #[cfg(feature = "overlapped-lists")] |
213 | | TooManyEvents(NonZeroUsize), |
214 | | } |
215 | | |
216 | | impl fmt::Display for DeError { |
217 | | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
218 | | match self { |
219 | | DeError::Custom(s) => write!(f, "{}", s), |
220 | | DeError::InvalidXml(e) => write!(f, "{}", e), |
221 | | DeError::InvalidInt(e) => write!(f, "{}", e), |
222 | | DeError::InvalidFloat(e) => write!(f, "{}", e), |
223 | | DeError::InvalidBoolean(v) => write!(f, "Invalid boolean value '{}'", v), |
224 | | DeError::KeyNotRead => write!(f, "Invalid `Deserialize` implementation: `MapAccess::next_value[_seed]` was called before `MapAccess::next_key[_seed]`"), |
225 | | DeError::UnexpectedStart(e) => { |
226 | | f.write_str("Unexpected `Event::Start(")?; |
227 | | write_byte_string(f, e)?; |
228 | | f.write_str(")`") |
229 | | } |
230 | | DeError::UnexpectedEnd(e) => { |
231 | | f.write_str("Unexpected `Event::End(")?; |
232 | | write_byte_string(f, e)?; |
233 | | f.write_str(")`") |
234 | | } |
235 | | DeError::UnexpectedEof => write!(f, "Unexpected `Event::Eof`"), |
236 | | DeError::ExpectedStart => write!(f, "Expecting `Event::Start`"), |
237 | | DeError::Unsupported(s) => write!(f, "Unsupported operation: {}", s), |
238 | | #[cfg(feature = "overlapped-lists")] |
239 | | DeError::TooManyEvents(s) => write!(f, "Deserializer buffers {} events, limit exceeded", s), |
240 | | } |
241 | | } |
242 | | } |
243 | | |
244 | | impl ::std::error::Error for DeError { |
245 | | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { |
246 | | match self { |
247 | | DeError::InvalidXml(e) => Some(e), |
248 | | DeError::InvalidInt(e) => Some(e), |
249 | | DeError::InvalidFloat(e) => Some(e), |
250 | | _ => None, |
251 | | } |
252 | | } |
253 | | } |
254 | | |
255 | | impl serde::de::Error for DeError { |
256 | | fn custom<T: fmt::Display>(msg: T) -> Self { |
257 | | DeError::Custom(msg.to_string()) |
258 | | } |
259 | | } |
260 | | |
261 | | impl serde::ser::Error for DeError { |
262 | | fn custom<T: fmt::Display>(msg: T) -> Self { |
263 | | DeError::Custom(msg.to_string()) |
264 | | } |
265 | | } |
266 | | |
267 | | impl From<Error> for DeError { |
268 | | #[inline] |
269 | | fn from(e: Error) -> Self { |
270 | | Self::InvalidXml(e) |
271 | | } |
272 | | } |
273 | | |
274 | | impl From<EscapeError> for DeError { |
275 | | #[inline] |
276 | | fn from(e: EscapeError) -> Self { |
277 | | Self::InvalidXml(e.into()) |
278 | | } |
279 | | } |
280 | | |
281 | | impl From<Utf8Error> for DeError { |
282 | | #[inline] |
283 | | fn from(e: Utf8Error) -> Self { |
284 | | Self::InvalidXml(e.into()) |
285 | | } |
286 | | } |
287 | | |
288 | | impl From<FromUtf8Error> for DeError { |
289 | | #[inline] |
290 | | fn from(e: FromUtf8Error) -> Self { |
291 | | Self::InvalidXml(e.into()) |
292 | | } |
293 | | } |
294 | | |
295 | | impl From<AttrError> for DeError { |
296 | | #[inline] |
297 | | fn from(e: AttrError) -> Self { |
298 | | Self::InvalidXml(e.into()) |
299 | | } |
300 | | } |
301 | | |
302 | | impl From<ParseIntError> for DeError { |
303 | | #[inline] |
304 | | fn from(e: ParseIntError) -> Self { |
305 | | Self::InvalidInt(e) |
306 | | } |
307 | | } |
308 | | |
309 | | impl From<ParseFloatError> for DeError { |
310 | | #[inline] |
311 | | fn from(e: ParseFloatError) -> Self { |
312 | | Self::InvalidFloat(e) |
313 | | } |
314 | | } |
315 | | |
316 | | impl From<fmt::Error> for DeError { |
317 | | #[inline] |
318 | | fn from(e: fmt::Error) -> Self { |
319 | | Self::Custom(e.to_string()) |
320 | | } |
321 | | } |
322 | | } |