1use std::path::{Path, PathBuf};
2
3#[derive(Debug)]
5pub struct Error {
6 pub(crate) kind: ErrorKind,
7 pub(crate) line: Option<u64>,
8 pub(crate) path: Option<PathBuf>,
9}
10
11#[derive(Debug)]
13pub enum ErrorKind {
14 Io(std::io::Error),
16 Parse(String),
18}
19
20impl Error {
21 pub(crate) fn parse(msg: String) -> Error {
23 Error { kind: ErrorKind::Parse(msg), line: None, path: None }
24 }
25
26 pub fn kind(&self) -> &ErrorKind {
28 &self.kind
29 }
30
31 pub fn line(&self) -> Option<u64> {
33 self.line
34 }
35
36 pub fn path(&self) -> Option<&Path> {
38 self.path.as_ref().map(|p| &**p)
39 }
40
41 pub fn into_kind(self) -> ErrorKind {
43 self.kind
44 }
45
46 pub fn is_io_error(&self) -> bool {
51 match self.kind {
52 ErrorKind::Io(_) => true,
53 _ => false,
54 }
55 }
56}
57
58impl std::error::Error for Error {}
59
60impl std::fmt::Display for Error {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 if let Some(ref path) = self.path {
63 if let Some(line) = self.line {
64 write!(f, "{}:{}: ", path.display(), line)?;
65 } else {
66 write!(f, "{}: ", path.display())?;
67 }
68 } else if let Some(line) = self.line {
69 write!(f, "error on line {}: ", line)?;
70 }
71 match self.kind {
72 ErrorKind::Io(ref err) => write!(f, "{}", err),
73 ErrorKind::Parse(ref msg) => write!(f, "{}", msg),
74 }
75 }
76}