1use std::io;
2use std::path::{Path, PathBuf};
3
4pub type Result<T> = std::result::Result<T, FsError>;
5
6#[derive(Debug, thiserror::Error)]
7pub enum FsError {
8 #[error("I/O failure on {path}: {source}")]
9 Io {
10 path: PathBuf,
11 #[source]
12 source: io::Error,
13 },
14 #[error("{0} is or traverses a symlink / reparse point, which is refused")]
15 Symlink(PathBuf),
16 #[error("{0} is not a directory")]
17 NotADirectory(PathBuf),
18 #[error("{0} is not a regular file")]
19 NotAFile(PathBuf),
20 #[error("{0} is not owned by the current user")]
21 NotOwned(PathBuf),
22 #[error("{0} is writable by group or others")]
23 TooPermissive(PathBuf),
24 #[error("directory identity changed while it was being pinned: {0}")]
25 IdentityChanged(PathBuf),
26 #[error("invalid entry name {0:?}")]
27 BadName(String),
28 #[error("{0} already exists")]
29 AlreadyExists(PathBuf),
30 #[error("{path} is {size} bytes, over the {limit} byte limit")]
31 TooLarge {
32 path: PathBuf,
33 size: u64,
34 limit: u64,
35 },
36 #[error("{path} is locked by {owner}")]
37 Locked { path: PathBuf, owner: String },
38 #[error("timed out after {waited_ms} ms waiting for lock {path}")]
39 LockTimeout { path: PathBuf, waited_ms: u64 },
40 #[error("entry cap of {0} exceeded")]
41 TooManyEntries(usize),
42 #[error("corrupt record {path}: {reason}")]
43 Corrupt { path: PathBuf, reason: String },
44 #[error("unknown stable id {0}")]
45 UnknownId(String),
46 #[error("platform primitive unavailable: {0}")]
47 Unavailable(&'static str),
48}
49
50impl FsError {
51 pub fn io(path: impl AsRef<Path>, source: io::Error) -> Self {
52 Self::Io {
53 path: path.as_ref().to_path_buf(),
54 source,
55 }
56 }
57
58 pub fn kind(&self) -> Option<io::ErrorKind> {
60 match self {
61 Self::Io { source, .. } => Some(source.kind()),
62 Self::AlreadyExists(_) => Some(io::ErrorKind::AlreadyExists),
63 _ => None,
64 }
65 }
66
67 pub fn is_not_found(&self) -> bool {
68 self.kind() == Some(io::ErrorKind::NotFound)
69 }
70}