]>
Commit | Line | Data |
---|---|---|
dfeec247 XL |
1 | use std::error; |
2 | use std::fmt; | |
3 | use std::io; | |
4 | use std::path::{Path, PathBuf}; | |
5 | ||
dfeec247 XL |
6 | /// Represents any kind of error that can occur while parsing the UCD. |
7 | #[derive(Debug)] | |
8 | pub struct Error { | |
9 | pub(crate) kind: ErrorKind, | |
10 | pub(crate) line: Option<u64>, | |
11 | pub(crate) path: Option<PathBuf>, | |
12 | } | |
13 | ||
14 | /// The kind of error that occurred while parsing the UCD. | |
15 | #[derive(Debug)] | |
16 | pub enum ErrorKind { | |
17 | /// An I/O error. | |
18 | Io(io::Error), | |
19 | /// A generic parse error. | |
20 | Parse(String), | |
21 | } | |
22 | ||
23 | impl Error { | |
3dfed10e XL |
24 | /// Create a new parse error from the given message. |
25 | pub(crate) fn parse(msg: String) -> Error { | |
26 | Error { kind: ErrorKind::Parse(msg), line: None, path: None } | |
27 | } | |
28 | ||
dfeec247 XL |
29 | /// Return the specific kind of this error. |
30 | pub fn kind(&self) -> &ErrorKind { | |
31 | &self.kind | |
32 | } | |
33 | ||
34 | /// Return the line number at which this error occurred, if available. | |
35 | pub fn line(&self) -> Option<u64> { | |
36 | self.line | |
37 | } | |
38 | ||
39 | /// Return the file path associated with this error, if one exists. | |
40 | pub fn path(&self) -> Option<&Path> { | |
41 | self.path.as_ref().map(|p| &**p) | |
42 | } | |
43 | ||
44 | /// Unwrap this error into its underlying kind. | |
45 | pub fn into_kind(self) -> ErrorKind { | |
46 | self.kind | |
47 | } | |
48 | ||
49 | /// Returns true if and only if this is an I/O error. | |
50 | /// | |
51 | /// If this returns true, the underlying `ErrorKind` is guaranteed to be | |
52 | /// `ErrorKind::Io`. | |
53 | pub fn is_io_error(&self) -> bool { | |
54 | match self.kind { | |
55 | ErrorKind::Io(_) => true, | |
56 | _ => false, | |
57 | } | |
58 | } | |
59 | } | |
60 | ||
61 | impl error::Error for Error { | |
dfeec247 XL |
62 | fn cause(&self) -> Option<&dyn error::Error> { |
63 | match self.kind { | |
64 | ErrorKind::Io(ref err) => Some(err), | |
65 | _ => None, | |
66 | } | |
67 | } | |
68 | } | |
69 | ||
70 | impl fmt::Display for Error { | |
3dfed10e | 71 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
dfeec247 XL |
72 | if let Some(ref path) = self.path { |
73 | if let Some(line) = self.line { | |
74 | write!(f, "{}:{}: ", path.display(), line)?; | |
75 | } else { | |
76 | write!(f, "{}: ", path.display())?; | |
77 | } | |
78 | } else if let Some(line) = self.line { | |
79 | write!(f, "error on line {}: ", line)?; | |
80 | } | |
81 | match self.kind { | |
82 | ErrorKind::Io(ref err) => write!(f, "{}", err), | |
83 | ErrorKind::Parse(ref msg) => write!(f, "{}", msg), | |
84 | } | |
85 | } | |
86 | } |