Skip to main content

fs_tree/
error.rs

1use std::{error, fmt, io, path::PathBuf};
2
3use file_type_enum::FileType;
4
5/// An alias for `Result<T, fs_tree::Error>`.
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// An enum for all errors generated in the `fs-tree` crate.
9#[derive(Debug)]
10pub enum Error {
11    /// Expected directory, but file type differs.
12    NotADirectory(PathBuf),
13    /// Expected regular file, but file type differs.
14    NotARegularFile(PathBuf),
15    /// Expected symlink, but file type differs.
16    NotASymlink(PathBuf),
17    /// Symlink exists but points to a different target than expected.
18    SymlinkTargetMismatch {
19        /// The path to the symlink.
20        path: PathBuf,
21        /// The expected target.
22        expected: PathBuf,
23        /// The actual target found.
24        found: PathBuf,
25    },
26    /// Unsupported file type found.
27    UnexpectedFileType(FileType, PathBuf),
28    /// An error with reading or writing.
29    Io(io::Error),
30}
31
32use Error::*;
33
34impl Error {
35    /// The path related to this error, if any.
36    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}