1 //! Error management module 2 3 /// The error type used by this crate. 4 #[derive(Debug)] 5 pub enum Error { 6 /// IO error 7 Io(::std::io::Error), 8 /// Utf8 error 9 Utf8(::std::str::Utf8Error), 10 /// Unexpected End of File 11 UnexpectedEof(String), 12 /// End event mismatch 13 EndEventMismatch { 14 /// Expected end event 15 expected: String, 16 /// Found end event 17 found: String, 18 }, 19 /// Unexpected token 20 UnexpectedToken(String), 21 /// Unexpected <!> 22 UnexpectedBang, 23 /// Text not found, expected `Event::Text` 24 TextNotFound, 25 /// `Event::XmlDecl` must start with *version* attribute 26 XmlDeclWithoutVersion(Option<String>), 27 /// Attribute Name contains quote 28 NameWithQuote(usize), 29 /// Attribute key not followed by with `=` 30 NoEqAfterName(usize), 31 /// Attribute value not quoted 32 UnquotedValue(usize), 33 /// Duplicate attribute 34 DuplicatedAttribute(usize, usize), 35 /// Escape error 36 EscapeError(::escape::EscapeError), 37 } 38 39 impl From<::std::io::Error> for Error { 40 /// Creates a new `Error::Io` from the given error 41 #[inline] from(error: ::std::io::Error) -> Error42 fn from(error: ::std::io::Error) -> Error { 43 Error::Io(error) 44 } 45 } 46 47 impl From<::std::str::Utf8Error> for Error { 48 /// Creates a new `Error::Utf8` from the given error 49 #[inline] from(error: ::std::str::Utf8Error) -> Error50 fn from(error: ::std::str::Utf8Error) -> Error { 51 Error::Utf8(error) 52 } 53 } 54 55 /// A specialized `Result` type where the error is hard-wired to [`Error`]. 56 /// 57 /// [`Error`]: enum.Error.html 58 pub type Result<T> = ::std::result::Result<T, Error>; 59 60 impl std::fmt::Display for Error { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result61 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 62 match self { 63 Error::Io(e) => write!(f, "I/O error: {}", e), 64 Error::Utf8(e) => write!(f, "UTF8 error: {}", e), 65 Error::UnexpectedEof(e) => write!(f, "Unexpected EOF during reading {}.", e), 66 Error::EndEventMismatch { expected, found } => { 67 write!(f, "Expecting </{}> found </{}>", expected, found) 68 } 69 Error::UnexpectedToken(e) => write!(f, "Unexpected token '{}'", e), 70 Error::UnexpectedBang => write!( 71 f, 72 "Only Comment, CDATA and DOCTYPE nodes can start with a '!'" 73 ), 74 Error::TextNotFound => write!(f, "Cannot read text, expecting Event::Text"), 75 Error::XmlDeclWithoutVersion(e) => write!( 76 f, 77 "XmlDecl must start with 'version' attribute, found {:?}", 78 e 79 ), 80 Error::NameWithQuote(e) => write!( 81 f, 82 "error while parsing attribute at position {}: \ 83 Attribute key cannot contain quote.", 84 e 85 ), 86 Error::NoEqAfterName(e) => write!( 87 f, 88 "error while parsing attribute at position {}: \ 89 Attribute key must be directly followed by = or space", 90 e 91 ), 92 Error::UnquotedValue(e) => write!( 93 f, 94 "error while parsing attribute at position {}: \ 95 Attribute value must start with a quote.", 96 e 97 ), 98 Error::DuplicatedAttribute(pos1, pos2) => write!( 99 f, 100 "error while parsing attribute at position {0}: \ 101 Duplicate attribute at position {1} and {0}", 102 pos1, pos2 103 ), 104 Error::EscapeError(e) => write!(f, "{}", e), 105 } 106 } 107 } 108 109 impl std::error::Error for Error { source(&self) -> Option<&(dyn std::error::Error + 'static)>110 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 111 match self { 112 Error::Io(e) => Some(e), 113 Error::Utf8(e) => Some(e), 114 Error::EscapeError(e) => Some(e), 115 _ => None, 116 } 117 } 118 } 119 120 #[cfg(feature = "serialize")] 121 pub mod serialize { 122 //! A module to handle serde (de)serialization errors 123 124 use super::Error; 125 use std::fmt; 126 127 /// (De)serialization error 128 #[derive(Debug)] 129 pub enum DeError { 130 /// Serde custom error 131 Custom(String), 132 /// Cannot parse to integer 133 Int(std::num::ParseIntError), 134 /// Cannot parse to float 135 Float(std::num::ParseFloatError), 136 /// Xml parsing error 137 Xml(Error), 138 /// Unexpected end of attributes 139 EndOfAttributes, 140 /// Unexpected end of file 141 Eof, 142 /// Invalid value for a boolean 143 InvalidBoolean(String), 144 /// Invalid unit value 145 InvalidUnit(String), 146 /// Invalid event for Enum 147 InvalidEnum(crate::events::Event<'static>), 148 /// Expecting Text event 149 Text, 150 /// Expecting Start event 151 Start, 152 /// Expecting End event 153 End, 154 /// Unsupported operation 155 Unsupported(&'static str), 156 } 157 158 impl fmt::Display for DeError { fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>159 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { 160 match self { 161 DeError::Custom(s) => write!(f, "{}", s), 162 DeError::Xml(e) => write!(f, "{}", e), 163 DeError::Int(e) => write!(f, "{}", e), 164 DeError::Float(e) => write!(f, "{}", e), 165 DeError::EndOfAttributes => write!(f, "Unexpected end of attributes"), 166 DeError::Eof => write!(f, "Unexpected `Event::Eof`"), 167 DeError::InvalidBoolean(v) => write!(f, "Invalid boolean value '{}'", v), 168 DeError::InvalidUnit(v) => { 169 write!(f, "Invalid unit value '{}', expected empty string", v) 170 } 171 DeError::InvalidEnum(e) => write!( 172 f, 173 "Invalid event for Enum, expecting Text or Start, got: {:?}", 174 e 175 ), 176 DeError::Text => write!(f, "Expecting Text event"), 177 DeError::Start => write!(f, "Expecting Start event"), 178 DeError::End => write!(f, "Expecting End event"), 179 DeError::Unsupported(s) => write!(f, "Unsupported operation {}", s), 180 } 181 } 182 } 183 184 impl ::std::error::Error for DeError { source(&self) -> Option<&(dyn std::error::Error + 'static)>185 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 186 match self { 187 DeError::Int(e) => Some(e), 188 DeError::Float(e) => Some(e), 189 DeError::Xml(e) => Some(e), 190 _ => None, 191 } 192 } 193 } 194 195 impl serde::de::Error for DeError { custom<T: fmt::Display>(msg: T) -> Self196 fn custom<T: fmt::Display>(msg: T) -> Self { 197 DeError::Custom(msg.to_string()) 198 } 199 } 200 201 impl serde::ser::Error for DeError { custom<T: fmt::Display>(msg: T) -> Self202 fn custom<T: fmt::Display>(msg: T) -> Self { 203 DeError::Custom(msg.to_string()) 204 } 205 } 206 207 impl From<Error> for DeError { from(e: Error) -> Self208 fn from(e: Error) -> Self { 209 DeError::Xml(e) 210 } 211 } 212 213 impl From<std::num::ParseIntError> for DeError { from(e: std::num::ParseIntError) -> Self214 fn from(e: std::num::ParseIntError) -> Self { 215 DeError::Int(e) 216 } 217 } 218 219 impl From<std::num::ParseFloatError> for DeError { from(e: std::num::ParseFloatError) -> Self220 fn from(e: std::num::ParseFloatError) -> Self { 221 DeError::Float(e) 222 } 223 } 224 } 225