use std::{error::Error as StdError, fmt};
pub struct BX(Box<dyn StdError>);
pub type Result<T, E = BX> = std::result::Result<T, E>;
impl BX {
    pub fn from_err(e: impl StdError + 'static) -> Self {
        Self(e.into())
    }
    pub fn from_boxed(e: Box<dyn StdError + 'static>) -> Self {
        Self(e)
    }
    pub fn from_string(s: String) -> Self {
        Self(s.into())
    }
}
pub fn box_error(e: impl StdError + 'static) -> BX {
    BX::from_err(e)
}
pub trait BxForErrors {
    fn bx(self) -> BX;
}
impl<E: StdError + 'static> BxForErrors for E {
    fn bx(self) -> BX {
        BX::from_err(self)
    }
}
pub trait BxForResults<T> {
    fn bx(self) -> Result<T, BX>;
}
impl<T, E: StdError + 'static> BxForResults<T> for Result<T, E> {
    fn bx(self) -> Result<T, BX> {
        self.map_err(BX::from_err)
    }
}
impl fmt::Debug for BX {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.fmt(f)
    }
}
impl fmt::Display for BX {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.fmt(f)
    }
}
impl StdError for BX {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        self.0.source()
    }
}
#[macro_export]
macro_rules! make_bxable {
    ($ty:ty) => {
        impl From<$ty> for $crate::BX {
            fn from(e: $ty) -> Self {
                $crate::BX::from_err(e)
            }
        }
    };
}
make_bxable!(std::io::Error);
make_bxable!(std::fmt::Error);
make_bxable!(std::str::Utf8Error);
make_bxable!(std::string::FromUtf8Error);
make_bxable!(std::string::FromUtf16Error);
make_bxable!(std::num::ParseIntError);
make_bxable!(std::num::ParseFloatError);
make_bxable!(std::num::TryFromIntError);
make_bxable!(std::array::TryFromSliceError);
make_bxable!(std::char::ParseCharError);
make_bxable!(std::net::AddrParseError);
make_bxable!(std::time::SystemTimeError);
make_bxable!(std::env::VarError);
make_bxable!(std::sync::mpsc::RecvError);
make_bxable!(std::sync::mpsc::TryRecvError);
make_bxable!(std::sync::mpsc::SendError<Box<dyn StdError + Send + Sync>>);
make_bxable!(std::sync::PoisonError<Box<dyn StdError + Send + Sync>>);
#[macro_export]
macro_rules! bail {
    ($err:expr) => {
        return Err($crate::BX::from_err($err));
    };
    ($fmt:expr, $($arg:tt)*) => {
        return Err($crate::BX::from_string(format!($fmt, $($arg)*)));
    };
}