use arcbox_error::CommonError;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, FsError>;
#[derive(Debug, Error)]
pub enum FsError {
#[error(transparent)]
Common(#[from] CommonError),
#[error("invalid path: {0}")]
InvalidPath(String),
#[error("operation not supported: {0}")]
NotSupported(String),
#[error("FUSE error: {0}")]
Fuse(String),
#[error("cache error: {0}")]
Cache(String),
#[error("invalid file handle: {0}")]
InvalidHandle(u64),
}
impl From<std::io::Error> for FsError {
fn from(err: std::io::Error) -> Self {
Self::Common(CommonError::from(err))
}
}
impl FsError {
#[must_use]
pub fn io(err: std::io::Error) -> Self {
Self::Common(CommonError::Io(err))
}
#[must_use]
pub fn not_found(path: impl Into<String>) -> Self {
Self::Common(CommonError::not_found(path))
}
#[must_use]
pub fn permission_denied(path: impl Into<String>) -> Self {
Self::Common(CommonError::permission_denied(path))
}
#[must_use]
pub fn is_not_found(&self) -> bool {
matches!(self, Self::Common(CommonError::NotFound(_)))
}
#[must_use]
pub fn to_errno(&self) -> i32 {
match self {
Self::Common(e) => Self::common_to_errno(e),
Self::InvalidPath(_) => libc::EINVAL,
Self::NotSupported(_) => libc::ENOSYS,
Self::Fuse(_) | Self::Cache(_) => libc::EIO,
Self::InvalidHandle(_) => libc::EBADF,
}
}
fn common_to_errno(err: &CommonError) -> i32 {
match err {
CommonError::Io(e) => e.raw_os_error().unwrap_or(libc::EIO),
CommonError::NotFound(_) => libc::ENOENT,
CommonError::PermissionDenied(_) => libc::EACCES,
CommonError::AlreadyExists(_) => libc::EEXIST,
CommonError::Config(_)
| CommonError::InvalidState(_)
| CommonError::Timeout(_)
| CommonError::Internal(_) => libc::EIO,
}
}
}