#![crate_name = "vg_errortools"]
#![warn(missing_docs)]
#![warn(unused_qualifications)]
#![deny(deprecated)]
use std::error::Error;
use std::fmt;
use std::fmt::{Debug, Display, Formatter};
#[cfg(feature = "tokio")]
use std::future::Future;
use std::path::{Path, PathBuf};
#[derive(Debug)]
pub struct FatIOError {
source: std::io::Error,
file: PathBuf,
}
impl FatIOError {
pub fn from_std_io_err(e: std::io::Error, file: PathBuf) -> Self {
FatIOError { source: e, file }
}
}
impl Display for FatIOError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Operating on file '{}' failed with error {}",
self.file.to_string_lossy(),
self.source
)?;
Ok(())
}
}
impl Error for FatIOError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.source)
}
}
pub fn fat_io_wrap_std<T, P: AsRef<Path>>(
path: P,
f: &dyn Fn(P) -> std::io::Result<T>,
) -> Result<T, FatIOError> {
let path_buf = path.as_ref().to_path_buf();
let result = f(path);
result.map_err(|e| FatIOError {
source: e,
file: path_buf,
})
}
#[cfg(feature = "tokio")]
pub async fn fat_io_wrap_tokio<T, P: AsRef<Path>, F: Future<Output = std::io::Result<T>>>(
path: P,
f: fn(P) -> F,
) -> Result<T, FatIOError> {
let path_buf = path.as_ref().to_path_buf();
let result = f(path).await;
result.map_err(|e| FatIOError {
source: e,
file: path_buf,
})
}
pub struct MainError(Box<dyn Error>);
impl<E: Into<Box<dyn Error>>> From<E> for MainError {
fn from(e: E) -> Self {
MainError(e.into())
}
}
impl Debug for MainError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(&self.0, f)?;
let mut source = self.0.source();
while let Some(error) = source {
write!(f, "\ncaused by: {}", error)?;
source = error.source();
}
Ok(())
}
}