Skip to main content

async_fs_io/
error.rs

1//! Typed errors returned by the asynchronous filesystem boundary.
2
3use std::path::Path;
4
5/// The filesystem operation that failed.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum Operation {
8    /// Reading file contents or metadata.
9    Read,
10    /// Writing, renaming, or removing file contents.
11    Write,
12    /// Creating, traversing, or removing directories.
13    Directory,
14    /// Acquiring or releasing a filesystem lock.
15    Lock,
16    /// Resolving a path before I/O begins.
17    PathResolution,
18}
19
20impl Operation {
21    /// Return the stable lower-case operation name.
22    #[must_use]
23    pub const fn name(self) -> &'static str {
24        match self {
25            Self::Read => "read",
26            Self::Write => "write",
27            Self::Directory => "directory",
28            Self::Lock => "lock",
29            Self::PathResolution => "path resolution",
30        }
31    }
32}
33
34/// Error from an asynchronous filesystem operation.
35#[derive(Debug, thiserror::Error)]
36pub enum FsError {
37    /// A file read operation failed.
38    #[error("file read error: {path}: {detail}")]
39    Read {
40        /// The path involved in the failed operation.
41        path: String,
42        /// Human-readable operating-system detail.
43        detail: String,
44    },
45    /// A file write operation failed.
46    #[error("file write error: {path}: {detail}")]
47    Write {
48        /// The path involved in the failed operation.
49        path: String,
50        /// Human-readable operating-system detail.
51        detail: String,
52    },
53    /// A directory operation failed.
54    #[error("directory error: {path}: {detail}")]
55    Directory {
56        /// The directory involved in the failed operation.
57        path: String,
58        /// Human-readable operating-system detail.
59        detail: String,
60    },
61    /// A filesystem lock operation failed.
62    #[error("lock error: {path}: {detail}")]
63    Lock {
64        /// The lock path involved in the failed operation.
65        path: String,
66        /// Human-readable operating-system detail.
67        detail: String,
68    },
69    /// A path could not be resolved before filesystem I/O began.
70    #[error("path resolution error: {0}")]
71    PathResolution(String),
72    /// A caller supplied an invalid bound or path relationship.
73    #[error("invalid filesystem request: {0}")]
74    InvalidRequest(String),
75}
76
77impl FsError {
78    /// Construct an error with the appropriate operation and path context.
79    #[must_use]
80    pub fn io(operation: Operation, path: &Path, detail: impl std::fmt::Display) -> Self {
81        let path = path.display().to_string();
82        let detail = detail.to_string();
83        match operation {
84            Operation::Read => Self::Read { path, detail },
85            Operation::Write => Self::Write { path, detail },
86            Operation::Directory => Self::Directory { path, detail },
87            Operation::Lock => Self::Lock { path, detail },
88            Operation::PathResolution => Self::PathResolution(detail),
89        }
90    }
91}