use crate::{Error, ErrorKind};
pub trait StackableErr {
type Output;
fn stack_err<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output;
fn stack_err_locationless<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output;
fn stack(self) -> Self::Output;
fn stack_locationless(self) -> Self::Output;
}
impl<T> StackableErr for core::result::Result<T, Error> {
type Output = core::result::Result<T, Error>;
#[track_caller]
fn stack_err<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
match self {
Ok(o) => Ok(o),
Err(e) => Err(e.add_kind(f())),
}
}
fn stack_err_locationless<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
match self {
Ok(o) => Ok(o),
Err(e) => Err(e.add_kind_locationless(f())),
}
}
#[track_caller]
fn stack(self) -> Self::Output {
match self {
Ok(o) => Ok(o),
Err(e) => Err(e.add_location()),
}
}
fn stack_locationless(self) -> Self::Output {
self
}
}
impl<T, E: std::error::Error + Send + Sync + 'static> StackableErr for core::result::Result<T, E> {
type Output = core::result::Result<T, Error>;
#[track_caller]
fn stack_err<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
match self {
Ok(o) => Ok(o),
Err(err) => Err(Error::from_box(Box::new(err)).add_kind_locationless(f())),
}
}
fn stack_err_locationless<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
match self {
Ok(o) => Ok(o),
Err(err) => Err(Error::from_box_locationless(Box::new(err)).add_kind_locationless(f())),
}
}
#[track_caller]
fn stack(self) -> Self::Output {
match self {
Ok(o) => Ok(o),
Err(err) => Err(Error::from_box(Box::new(err))),
}
}
fn stack_locationless(self) -> Self::Output {
match self {
Ok(o) => Ok(o),
Err(err) => Err(Error::from_box_locationless(Box::new(err))),
}
}
}
impl<T> StackableErr for Option<T> {
type Output = core::result::Result<T, Error>;
#[track_caller]
fn stack_err<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
match self {
Some(o) => Ok(o),
None => Err(Error::from_kind(f())),
}
}
fn stack_err_locationless<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
match self {
Some(o) => Ok(o),
None => Err(Error::from_kind_locationless(f())),
}
}
#[track_caller]
fn stack(self) -> Self::Output {
match self {
Some(o) => Ok(o),
None => Err(Error::new()),
}
}
fn stack_locationless(self) -> Self::Output {
match self {
Some(o) => Ok(o),
None => Err(Error::empty()),
}
}
}
impl StackableErr for Error {
type Output = core::result::Result<(), Error>;
#[track_caller]
fn stack_err<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
Err(self.add_kind(f()))
}
fn stack_err_locationless<K: Into<ErrorKind>, F: FnOnce() -> K>(self, f: F) -> Self::Output {
Err(self.add_kind_locationless(f()))
}
#[track_caller]
fn stack(self) -> Self::Output {
Err(self.add_location())
}
fn stack_locationless(self) -> Self::Output {
Err(self)
}
}