pub use anyhow::{Context, Error as AnyError, Result as AnyResult, anyhow}; use std::{
error::Error as StdError,
fmt::{Debug, Display, Formatter, Result as FmtResult},
result::Result as StdResult,
};
pub use std::{ffi::OsStr, path::Path};
#[derive(Debug)]
pub struct Error(pub anyhow::Error);
pub type Result<T, E = Error> = StdResult<T, E>;
impl<E> From<E> for Error
where
E: Into<AnyError>,
{
#[track_caller]
fn from(e: E) -> Self {
let caller = std::panic::Location::caller();
let fullname = OsStr::new(caller.file());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(e.into().context(anyhow!("({}:{})", name.display(), caller.line())))
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
Display::fmt(&self.0.chain().map(|e| e.to_string() + " ").collect::<String>(), f)
}
}
impl Error {
#[inline(always)]
pub fn is<E>(&self) -> bool
where
E: Display + Debug + Send + Sync + 'static,
{
self.0.is::<E>()
}
}
pub mod cauz2 {
#[inline(always)]
#[allow(non_snake_case)]
pub fn Ok<T>(value: T) -> super::Result<T> {
super::Result::<T>::Ok(value)
}
}
#[macro_export]
macro_rules! err {
() => {{
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(anyhow!("({}:{})", name.display(), line!()))
}};
($msg:literal) => {{
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(anyhow!("({}:{}) {}", name.display(), line!(), $msg))
}};
($err:ident) => {{
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(anyhow!($err).context(anyhow!("({}:{}) ", name.display(), line!())))
}};
($fmt:literal, $($args:tt)*) => {{
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(anyhow!("({}:{}) {}", name.display(), line!(), format!($fmt, $($args)*)))
}};
($err:ident, $($args:tt)*) => {{
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(anyhow!($err).context(anyhow!("({}:{}) {}", name.display(), line!(), format!($($args)*))))
}};
($err:expr) => {{
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(anyhow!("({}:{}) {:?}", name.display(), line!(), $err))
}};
}
#[macro_export]
macro_rules! err2 {
($fmt:literal, $($args:tt)*) => {
|x: AnyError| {
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(x.context(anyhow!("({}:{}) {}", name.display(), line!(), format!($fmt, $($args)*))))
}
};
($err:ident, $($args:tt)*) => {
|x: AnyError| {
let fullname = OsStr::new(file!());
let name = Path::new(fullname).file_name().unwrap_or(fullname);
Error(x.context($err).context(anyhow!("({}:{}) {}", name.display(), line!(), format!($($args)*))))
}
};
}
pub trait Cauz<T> {
fn cauz(self) -> AnyResult<T>; }
impl<T> Cauz<T> for Result<T> {
#[inline(always)]
fn cauz(self) -> AnyResult<T> {
self.map_err(|e| e.0)
}
}
impl<T> Cauz<T> for StdResult<T, Box<dyn StdError + Send + Sync>> {
#[inline(always)]
fn cauz(self) -> AnyResult<T> {
self.map_err(|e| anyhow!(e))
}
}
impl<T> Cauz<T> for Option<T> {
#[inline(always)]
fn cauz(self) -> AnyResult<T> {
self.ok_or(anyhow!(""))
}
}
impl Cauz<()> for bool {
#[inline(always)]
fn cauz(self) -> AnyResult<()> {
self.then_some(()).ok_or(anyhow!("")) }
}
pub trait Cauz2<C, T> {
fn cauz2(self, cause: C) -> AnyResult<T>; }
impl<C, T> Cauz2<C, T> for Result<T>
where
C: Display + Send + Sync + 'static,
{
#[inline(always)]
fn cauz2(self, cause: C) -> AnyResult<T> {
self.map_err(|e| e.0.context(cause))
}
}
impl<C, T, E> Cauz2<C, T> for StdResult<T, E>
where
C: Display + Send + Sync + 'static,
E: Into<AnyError>,
{
#[inline(always)]
fn cauz2(self, cause: C) -> AnyResult<T> {
self.map_err(|e| anyhow!(e).context(cause))
}
}
impl<C, T> Cauz2<C, T> for Option<T>
where
C: Display + Send + Sync + 'static,
{
#[inline(always)]
fn cauz2(self, cause: C) -> AnyResult<T> {
self.ok_or(anyhow!("{}", cause))
}
}
impl<C> Cauz2<C, ()> for bool
where
C: Display + Send + Sync + 'static,
{
#[inline(always)]
fn cauz2(self, cause: C) -> AnyResult<()> {
self.then_some(()).ok_or(anyhow!("{}", cause)) }
}
pub trait Cauz3<T, E> {
fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E>;
}
impl<T, E> Cauz3<T, E> for Result<T> {
#[inline(always)]
fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E> {
self.map_err(|e| cause(e.0))
}
}
impl<T, E0, E> Cauz3<T, E> for StdResult<T, E0>
where
E0: Into<AnyError>,
{
#[inline(always)]
fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E> {
self.map_err(|e| cause(e.into()))
}
}
impl<T, E> Cauz3<T, E> for Option<T> {
#[inline(always)]
fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E> {
self.ok_or_else(|| cause(anyhow!("")))
}
}
impl<E> Cauz3<(), E> for bool {
#[inline(always)]
fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<(), E> {
self.then_some(()).ok_or_else(|| cause(anyhow!(""))) }
}