Coverage Report

Created: 2025-11-09 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}