use std::path::PathBuf;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
#[error("I/O error: {source}")]
Io {
#[from]
source: std::io::Error,
},
#[error("Corrupted object at {path}: {reason}")]
CorruptedObject { path: PathBuf, reason: String },
#[error("Invalid hash: {reason}")]
InvalidHash { reason: String },
#[error("Object not found: {hash}")]
ObjectNotFound { hash: String },
#[error("Invalid store at {path}: {reason}")]
InvalidStore { path: PathBuf, reason: String },
#[error("Invalid reference: {reason}")]
InvalidRef { reason: String },
#[error("Reference not found: {name}")]
RefNotFound { name: String },
#[error("Invalid object type: expected {expected}, got {got}")]
InvalidObjectType { expected: String, got: String },
#[error("Path already exists: {path}")]
PathExists { path: PathBuf },
#[error("UTF-8 error: {source}")]
Utf8Error {
#[from]
source: std::str::Utf8Error,
},
#[error("Invalid tree entry: {reason}")]
InvalidTreeEntry { reason: String },
#[error("Unsupported algorithm: {algorithm}")]
UnsupportedAlgorithm { algorithm: String },
}
impl Error {
pub fn corrupted_object(path: impl Into<PathBuf>, reason: impl Into<String>) -> Self {
Error::CorruptedObject {
path: path.into(),
reason: reason.into(),
}
}
pub fn invalid_hash(reason: impl Into<String>) -> Self {
Error::InvalidHash {
reason: reason.into(),
}
}
pub fn object_not_found(hash: impl Into<String>) -> Self {
Error::ObjectNotFound { hash: hash.into() }
}
pub fn invalid_store(path: impl Into<PathBuf>, reason: impl Into<String>) -> Self {
Error::InvalidStore {
path: path.into(),
reason: reason.into(),
}
}
pub fn invalid_ref(reason: impl Into<String>) -> Self {
Error::InvalidRef {
reason: reason.into(),
}
}
pub fn ref_not_found(name: impl Into<String>) -> Self {
Error::RefNotFound { name: name.into() }
}
pub fn invalid_object_type(expected: impl Into<String>, got: impl Into<String>) -> Self {
Error::InvalidObjectType {
expected: expected.into(),
got: got.into(),
}
}
pub fn path_exists(path: impl Into<PathBuf>) -> Self {
Error::PathExists { path: path.into() }
}
pub fn invalid_tree_entry(reason: impl Into<String>) -> Self {
Error::InvalidTreeEntry {
reason: reason.into(),
}
}
pub fn unsupported_algorithm(algorithm: impl Into<String>) -> Self {
Error::UnsupportedAlgorithm {
algorithm: algorithm.into(),
}
}
}
impl From<tempfile::PersistError> for Error {
fn from(err: tempfile::PersistError) -> Self {
Error::Io { source: err.error }
}
}
impl From<ignore::Error> for Error {
fn from(err: ignore::Error) -> Self {
match err.io_error() {
Some(io_err) => Error::Io {
source: std::io::Error::new(io_err.kind(), io_err.to_string()),
},
None => Error::Io {
source: std::io::Error::other(err.to_string()),
},
}
}
}