use std::fmt;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VfsError {
NotFound(PathBuf),
AlreadyExists(PathBuf),
NotADirectory(PathBuf),
NotAFile(PathBuf),
IsADirectory(PathBuf),
PermissionDenied(PathBuf),
DirectoryNotEmpty(PathBuf),
SymlinkLoop(PathBuf),
InvalidPath(String),
IoError(String),
}
impl fmt::Display for VfsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VfsError::NotFound(p) => write!(f, "No such file or directory: {}", p.display()),
VfsError::AlreadyExists(p) => write!(f, "Already exists: {}", p.display()),
VfsError::NotADirectory(p) => write!(f, "Not a directory: {}", p.display()),
VfsError::NotAFile(p) => write!(f, "Not a file: {}", p.display()),
VfsError::IsADirectory(p) => write!(f, "Is a directory: {}", p.display()),
VfsError::PermissionDenied(p) => write!(f, "Permission denied: {}", p.display()),
VfsError::DirectoryNotEmpty(p) => write!(f, "Directory not empty: {}", p.display()),
VfsError::SymlinkLoop(p) => {
write!(f, "Too many levels of symbolic links: {}", p.display())
}
VfsError::InvalidPath(msg) => write!(f, "Invalid path: {msg}"),
VfsError::IoError(msg) => write!(f, "I/O error: {msg}"),
}
}
}
impl std::error::Error for VfsError {}
#[derive(Debug)]
pub enum RustBashError {
Parse(String),
Execution(String),
ExpansionError {
message: String,
exit_code: i32,
should_exit: bool,
},
FailGlob {
pattern: String,
},
RedirectFailed(String),
LimitExceeded {
limit_name: &'static str,
limit_value: usize,
actual_value: usize,
},
Network(String),
Vfs(VfsError),
Timeout,
}
impl fmt::Display for RustBashError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RustBashError::Parse(msg) => write!(f, "parse error: {msg}"),
RustBashError::Execution(msg) => write!(f, "execution error: {msg}"),
RustBashError::ExpansionError { message, .. } => {
write!(f, "expansion error: {message}")
}
RustBashError::FailGlob { pattern } => {
write!(f, "no match: {pattern}")
}
RustBashError::RedirectFailed(msg) => write!(f, "rust-bash: {msg}"),
RustBashError::LimitExceeded {
limit_name,
limit_value,
actual_value,
} => write!(
f,
"limit exceeded: {limit_name} ({actual_value}) exceeded limit ({limit_value})"
),
RustBashError::Network(msg) => write!(f, "network error: {msg}"),
RustBashError::Vfs(e) => write!(f, "vfs error: {e}"),
RustBashError::Timeout => write!(f, "execution timed out"),
}
}
}
impl std::error::Error for RustBashError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
RustBashError::Vfs(e) => Some(e),
_ => None,
}
}
}
impl From<VfsError> for RustBashError {
fn from(e: VfsError) -> Self {
RustBashError::Vfs(e)
}
}