use std::path::PathBuf;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, VfsError>;
#[derive(Error, Debug)]
pub enum VfsError {
#[error("not found: {0}")]
NotFound(PathBuf),
#[error("already exists: {0}")]
AlreadyExists(PathBuf),
#[error("not a directory: {0}")]
NotADirectory(PathBuf),
#[error("not a file: {0}")]
NotAFile(PathBuf),
#[error("directory not empty: {0}")]
NotEmpty(PathBuf),
#[error("invalid path: {0}")]
InvalidPath(String),
#[error("invalid input: {0}")]
InvalidInput(String),
#[error("vault not found: {0}")]
VaultNotFound(String),
#[error("vault already exists: {0}")]
VaultExists(String),
#[error("no active vault - run 'avfs vault create <name>' or 'avfs vault use <name>'")]
NoActiveVault,
#[error("quota exceeded: {0}")]
QuotaExceeded(String),
#[error("sqlite error: {0}")]
Storage(#[from] rusqlite::Error),
#[cfg(feature = "sled-backend")]
#[error("sled error: {0}")]
Sled(#[from] sled::Error),
#[cfg(feature = "lmdb-backend")]
#[error("lmdb error: {0}")]
Lmdb(#[from] heed::Error),
#[cfg(any(feature = "sled-backend", feature = "lmdb-backend"))]
#[error("tantivy error: {0}")]
Tantivy(#[from] tantivy::TantivyError),
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("json error: {0}")]
Json(#[from] serde_json::Error),
#[error("command exited with code {0}")]
ExitStatus(i32),
#[error("internal error: {0}")]
Internal(String),
}
impl VfsError {
pub fn to_json(&self) -> serde_json::Value {
let (error_type, message, path) = match self {
VfsError::NotFound(p) => ("NotFound", self.to_string(), Some(p.display().to_string())),
VfsError::AlreadyExists(p) => {
("AlreadyExists", self.to_string(), Some(p.display().to_string()))
}
VfsError::NotADirectory(p) => {
("NotADirectory", self.to_string(), Some(p.display().to_string()))
}
VfsError::NotAFile(p) => {
("NotAFile", self.to_string(), Some(p.display().to_string()))
}
VfsError::NotEmpty(p) => {
("NotEmpty", self.to_string(), Some(p.display().to_string()))
}
VfsError::InvalidPath(s) => ("InvalidPath", self.to_string(), Some(s.clone())),
VfsError::InvalidInput(s) => ("InvalidInput", self.to_string(), Some(s.clone())),
VfsError::VaultNotFound(s) => ("VaultNotFound", self.to_string(), Some(s.clone())),
VfsError::VaultExists(s) => ("VaultExists", self.to_string(), Some(s.clone())),
VfsError::NoActiveVault => ("NoActiveVault", self.to_string(), None),
VfsError::QuotaExceeded(s) => ("QuotaExceeded", self.to_string(), Some(s.clone())),
VfsError::Storage(e) => ("StorageError", e.to_string(), None),
VfsError::Io(e) => ("IoError", e.to_string(), None),
VfsError::Json(e) => ("JsonError", e.to_string(), None),
VfsError::ExitStatus(code) => ("ExitStatus", self.to_string(), Some(code.to_string())),
VfsError::Internal(s) => ("InternalError", s.clone(), None),
#[cfg(feature = "sled-backend")]
VfsError::Sled(e) => ("SledError", e.to_string(), None),
#[cfg(feature = "lmdb-backend")]
VfsError::Lmdb(e) => ("LmdbError", e.to_string(), None),
#[cfg(any(feature = "sled-backend", feature = "lmdb-backend"))]
VfsError::Tantivy(e) => ("TantivyError", e.to_string(), None),
};
let mut json = serde_json::json!({
"error": error_type,
"message": message,
});
if let Some(p) = path {
json["path"] = serde_json::Value::String(p);
}
json
}
}