1use crate::escape::EscapeError;
4use crate::events::attributes::AttrError;
5use crate::utils::write_byte_string;
6use std::fmt;
7use std::io::Error as IoError;
8use std::str::Utf8Error;
9use std::string::FromUtf8Error;
10use std::sync::Arc;
11
12#[derive(Clone, Debug)]
14pub enum Error {
15 Io(Arc<IoError>),
19 NonDecodable(Option<Utf8Error>),
22 UnexpectedEof(String),
24 EndEventMismatch {
26 expected: String,
28 found: String,
30 },
31 UnexpectedToken(String),
33 UnexpectedBang(u8),
35 TextNotFound,
37 XmlDeclWithoutVersion(Option<String>),
40 EmptyDocType,
44 InvalidAttr(AttrError),
46 EscapeError(EscapeError),
48 UnknownPrefix(Vec<u8>),
50}
51
52impl From<IoError> for Error {
53 #[inline]
55 fn from(error: IoError) -> Error {
56 Error::Io(Arc::new(error))
57 }
58}
59
60impl From<Utf8Error> for Error {
61 #[inline]
63 fn from(error: Utf8Error) -> Error {
64 Error::NonDecodable(Some(error))
65 }
66}
67
68impl From<FromUtf8Error> for Error {
69 #[inline]
71 fn from(error: FromUtf8Error) -> Error {
72 error.utf8_error().into()
73 }
74}
75
76impl From<EscapeError> for Error {
77 #[inline]
79 fn from(error: EscapeError) -> Error {
80 Error::EscapeError(error)
81 }
82}
83
84impl From<AttrError> for Error {
85 #[inline]
86 fn from(error: AttrError) -> Self {
87 Error::InvalidAttr(error)
88 }
89}
90
91pub type Result<T> = std::result::Result<T, Error>;
93
94impl fmt::Display for Error {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 match self {
97 Error::Io(e) => write!(f, "I/O error: {}", e),
98 Error::NonDecodable(None) => write!(f, "Malformed input, decoding impossible"),
99 Error::NonDecodable(Some(e)) => write!(f, "Malformed UTF-8 input: {}", e),
100 Error::UnexpectedEof(e) => write!(f, "Unexpected EOF during reading {}", e),
101 Error::EndEventMismatch { expected, found } => {
102 write!(f, "Expecting </{}> found </{}>", expected, found)
103 }
104 Error::UnexpectedToken(e) => write!(f, "Unexpected token '{}'", e),
105 Error::UnexpectedBang(b) => write!(
106 f,
107 "Only Comment (`--`), CDATA (`[CDATA[`) and DOCTYPE (`DOCTYPE`) nodes can start with a '!', but symbol `{}` found",
108 *b as char
109 ),
110 Error::TextNotFound => write!(f, "Cannot read text, expecting Event::Text"),
111 Error::XmlDeclWithoutVersion(e) => write!(
112 f,
113 "XmlDecl must start with 'version' attribute, found {:?}",
114 e
115 ),
116 Error::EmptyDocType => write!(f, "DOCTYPE declaration must not be empty"),
117 Error::InvalidAttr(e) => write!(f, "error while parsing attribute: {}", e),
118 Error::EscapeError(e) => write!(f, "{}", e),
119 Error::UnknownPrefix(prefix) => {
120 f.write_str("Unknown namespace prefix '")?;
121 write_byte_string(f, prefix)?;
122 f.write_str("'")
123 }
124 }
125 }
126}
127
128impl std::error::Error for Error {
129 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
130 match self {
131 Error::Io(e) => Some(e),
132 Error::NonDecodable(Some(e)) => Some(e),
133 Error::InvalidAttr(e) => Some(e),
134 Error::EscapeError(e) => Some(e),
135 _ => None,
136 }
137 }
138}
139
140#[cfg(feature = "serialize")]
141pub mod serialize {
142 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 #[derive(Clone, Debug)]
153 pub enum DeError {
154 Custom(String),
156 InvalidXml(Error),
158 InvalidInt(ParseIntError),
160 InvalidFloat(ParseFloatError),
162 InvalidBoolean(String),
164 KeyNotRead,
170 UnexpectedStart(Vec<u8>),
174 UnexpectedEnd(Vec<u8>),
182 UnexpectedEof,
191 ExpectedStart,
197 Unsupported(Cow<'static, str>),
210 #[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}