use std::{io, path::PathBuf};
#[derive(Debug)]
pub enum Error {
SourcePathNotADirectory(PathBuf),
Io(io::Error),
Annotated(String, Box<dyn std::error::Error>),
}
impl Error {
pub fn annotated<S, E>(anno: S, err: E) -> Self
where
S: Into<String>,
E: std::error::Error + 'static,
{
Error::Annotated(anno.into(), Box::new(err))
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::SourcePathNotADirectory(path) => {
write!(
f,
"Source path is not a directory, or can not be opened: {:?}",
path
)
}
Error::Io(io) => io.fmt(f),
Error::Annotated(anno, e) => {
write!(f, "{}: {}", anno, e)
}
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Io(ioerr) => Some(ioerr),
_ => None,
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Error::Io(err)
}
}
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) trait ResultExt<T, A: Into<String>> {
fn annotate_err(self, anno: A) -> Result<T>;
}
impl<T, E, A> ResultExt<T, A> for std::result::Result<T, E>
where
E: std::error::Error + 'static,
A: Into<String>,
{
fn annotate_err(self, anno: A) -> Result<T> {
self.map_err(|err| Error::annotated(anno, err))
}
}