1use std::{error, fmt, io, path::PathBuf};
2
3use file_type_enum::FileType;
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Debug)]
10pub enum Error {
11 NotADirectory(PathBuf),
13 NotARegularFile(PathBuf),
15 NotASymlink(PathBuf),
17 SymlinkTargetMismatch {
19 path: PathBuf,
21 expected: PathBuf,
23 found: PathBuf,
25 },
26 UnexpectedFileType(FileType, PathBuf),
28 Io(io::Error),
30}
31
32use Error::*;
33
34impl Error {
35 pub fn path(&self) -> Option<&PathBuf> {
37 match self {
38 NotADirectory(path)
39 | NotARegularFile(path)
40 | NotASymlink(path)
41 | SymlinkTargetMismatch { path, .. }
42 | UnexpectedFileType(_, path) => Some(path),
43 Io(..) => None,
44 }
45 }
46}
47
48impl error::Error for Error {
49 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
50 match self {
51 Io(source) => Some(source),
52 _ => None,
53 }
54 }
55}
56
57impl fmt::Display for Error {
58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59 match self {
60 NotADirectory(path) => write!(f, "not a directory: {}", path.display()),
61 NotARegularFile(path) => write!(f, "not a regular file: {}", path.display()),
62 NotASymlink(path) => write!(f, "not a symlink: {}", path.display()),
63 SymlinkTargetMismatch {
64 path,
65 expected,
66 found,
67 } => {
68 write!(
69 f,
70 "symlink target mismatch at {}: expected {}, found {}",
71 path.display(),
72 expected.display(),
73 found.display(),
74 )
75 },
76 UnexpectedFileType(file_type, path) => {
77 write!(
78 f,
79 "unexpected file type {:?}: {}",
80 file_type,
81 path.display(),
82 )
83 },
84 Io(inner) => inner.fmt(f),
85 }
86 }
87}
88
89impl From<io::Error> for Error {
90 fn from(err: io::Error) -> Self {
91 Error::Io(err)
92 }
93}