#[allow(unused_imports)]
pub use anyhow::{Context, Error as AnyError, Result as AnyResult, anyhow}; use std::{
any::type_name,
fmt::{Debug, Display, Formatter, Result as FmtResult},
result::Result as StdResult,
};
#[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<anyhow::Error>,
{
#[track_caller]
fn from(e: E) -> Self {
let caller = std::panic::Location::caller();
Error(anyhow!(e).context(anyhow!("{:?}", (caller.file(), 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 {
() => {
Error(anyhow!("{:?} ", (file!(), line!())))
};
($msg:literal) => {
Error(anyhow!("{:?} {}", (file!(), line!()), $msg))
};
($err:ident) => {
Error(anyhow!("{:?} {}", (file!(), line!()), $err))
};
($err:ident, $($args:tt)*) => {
|| Error(anyhow!("{:?} {} {}", (file!(), line!()), format!($($args)*), $err))
};
($fmt:literal, $($args:tt)*) => {
|| Error(anyhow!("{:?} {}", (file!(), line!()), format!($fmt, $($args)*)))
};
($err:expr) => {
Error(anyhow!("{:?} {:?}", (file!(), line!()), $err))
};
}
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 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<anyhow::Error>,
{
#[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<C, T, E> {
fn cauz3(self, cause: impl FnOnce() -> C, op: impl Fn(AnyError) -> E) -> StdResult<T, E>;
}
impl<C, T, E> Cauz3<C, T, E> for Result<T>
where
C: Display + Send + Sync + 'static,
{
#[inline(always)]
#[track_caller]
fn cauz3(self, cause: impl FnOnce() -> C, op: impl Fn(AnyError) -> E) -> StdResult<T, E> {
self.map_err(|e| {
match type_name::<E>() {
t if t == type_name::<Error>() => op(e.0.context(cause())),
t if t == type_name::<AnyError>() => op(e.0.context(cause())),
_ => op(anyhow!(Error(e.0.context(cause())).to_string())),
}
})
}
}
impl<C, T, E, E0> Cauz3<C, T, E> for StdResult<T, E0>
where
C: Display + Send + Sync + 'static,
E0: Into<anyhow::Error>,
{
#[inline(always)]
#[track_caller]
fn cauz3(self, cause: impl FnOnce() -> C, op: impl Fn(AnyError) -> E) -> StdResult<T, E> {
self.map_err(|e| {
match type_name::<E>() {
t if t == type_name::<Error>() => op(anyhow!(e).context(cause())),
t if t == type_name::<AnyError>() => op(anyhow!(e).context(cause())),
_ => op(anyhow!(Error(anyhow!(e).context(cause())).to_string())),
}
})
}
}
impl<C, T, E> Cauz3<C, T, E> for Option<T>
where
C: Display + Send + Sync + 'static,
{
#[inline(always)]
fn cauz3(self, cause: impl FnOnce() -> C, op: impl Fn(AnyError) -> E) -> StdResult<T, E> {
self.ok_or_else(|| {
match type_name::<E>() {
t if t == type_name::<Error>() => op(anyhow!("{}", cause())),
t if t == type_name::<AnyError>() => op(anyhow!("{}", cause())),
_ => op(anyhow!("{}", cause())),
}
})
}
}
impl<C, E> Cauz3<C, (), E> for bool
where
C: Display + Send + Sync + 'static,
{
#[inline(always)]
fn cauz3(self, cause: impl FnOnce() -> C, op: impl Fn(AnyError) -> E) -> StdResult<(), E> {
self.then_some(()).ok_or_else(|| {
match type_name::<E>() {
t if t == type_name::<Error>() => op(anyhow!("{}", cause())),
t if t == type_name::<AnyError>() => op(anyhow!("{}", cause())),
_ => op(anyhow!("{}", cause())),
}
})
}
}