#![doc = include_str!("../README.md")]
use std::fmt::Debug;
pub trait Z {
type Error;
fn long_form(&self) -> String;
fn with_info<X: Debug>(self, name: &str, value: X) -> Self::Error;
fn with_lazy_info<F: FnOnce() -> String>(self, name: &str, value: F) -> Self::Error;
}
impl<T, E: Z<Error = E>> Z for Result<T, E> {
type Error = Result<T, E>;
fn long_form(&self) -> String {
match self {
Ok(_) => {
panic!("called long_form() on Ok Result");
}
Err(e) => e.long_form(),
}
}
fn with_info<X: Debug>(self, name: &str, value: X) -> Self::Error {
match self {
Ok(_) => self,
Err(e) => Err(e.with_info(name, value)),
}
}
fn with_lazy_info<F: FnOnce() -> String>(self, name: &str, value: F) -> Self::Error {
match self {
Ok(_) => self,
Err(e) => Err(e.with_info(name, value())),
}
}
}
#[macro_export]
macro_rules! iotoz {
($error:ident) => {
pub trait IoToZ<T>: Sized
where
$error: Z,
{
#[allow(clippy::wrong_self_convention)]
fn as_z(self) -> Result<T, $error>;
fn pretty_unwrap(self) -> T;
}
impl<T, E: Into<$error>> IoToZ<T> for Result<T, E> {
fn as_z(self) -> Result<T, $error> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(e.into()),
}
}
fn pretty_unwrap(self) -> T {
match self {
Ok(t) => t,
Err(err) => {
let err: $error = err.into();
panic!("{}", err.long_form());
}
}
}
}
};
}