use crate::{builder::OofBuilder, tags::Tags};
use core::fmt;
use std::{convert::Infallible, error::Error};
pub trait OofExt: Sized {
type Return;
type Error: 'static + Send + Sync + Error;
fn _context<D: ToString>(self, context: D) -> Result<Self::Return, OofBuilder<Self::Error>>;
fn _tag<Tag: 'static>(self) -> Result<Self::Return, OofBuilder<Self::Error>>;
fn _tag_if<Tag: 'static, F: FnOnce(&Self::Error) -> bool>(
self,
f: F,
) -> Result<Self::Return, OofBuilder<Self::Error>>;
fn _tag_manually<F: FnOnce(&Self::Error, &mut Tags)>(
self,
f: F,
) -> Result<Self::Return, OofBuilder<Self::Error>>;
fn _attach<D: fmt::Debug>(self, debuggable: D)
-> Result<Self::Return, OofBuilder<Self::Error>>;
fn _attach_lazy<D: ToString, F: FnOnce() -> D>(
self,
f: F,
) -> Result<Self::Return, OofBuilder<Self::Error>>;
}
impl<T, E> OofExt for Result<T, E>
where
E: 'static + Send + Sync + Error,
{
type Return = T;
type Error = E;
#[cfg_attr(feature = "location", track_caller)]
fn _context<D: ToString>(self, context: D) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(OofBuilder::new().with_custom(context).with_source(e)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _tag<Tag: 'static>(self) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(OofBuilder::new().with_source(e).with_tag::<Tag>()),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _tag_if<Tag: 'static, F: FnOnce(&Self::Error) -> bool>(
self,
f: F,
) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(OofBuilder::new().with_source(e).with_tag_if::<Tag, _>(f)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _tag_manually<F: FnOnce(&Self::Error, &mut Tags)>(
self,
f: F,
) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(OofBuilder::new().with_source(e).with_tag_manually(f)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _attach<D: fmt::Debug>(
self,
debuggable: D,
) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(OofBuilder::new().with_source(e).with_attachment(debuggable)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _attach_lazy<D: ToString, F: FnOnce() -> D>(
self,
f: F,
) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(OofBuilder::new().with_source(e).with_attachment_lazy(f)),
}
}
}
impl<T> OofExt for Option<T> {
type Return = T;
type Error = Infallible;
#[cfg_attr(feature = "location", track_caller)]
fn _context<D: ToString>(self, context: D) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Some(t) => Ok(t),
None => Err(OofBuilder::new().with_custom(context)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _tag<Tag: 'static>(self) -> Result<T, OofBuilder> {
match self {
Some(t) => Ok(t),
None => Err(OofBuilder::new().with_tag::<Tag>()),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _tag_if<Tag: 'static, F: FnOnce(&Self::Error) -> bool>(self, f: F) -> Result<T, OofBuilder> {
match self {
Some(t) => Ok(t),
None => Err(OofBuilder::new().with_tag_if::<Tag, _>(f)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _tag_manually<F: FnOnce(&Self::Error, &mut Tags)>(
self,
f: F,
) -> Result<Self::Return, OofBuilder<Self::Error>> {
match self {
Some(t) => Ok(t),
None => Err(OofBuilder::new().with_tag_manually(f)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _attach<D: fmt::Debug>(self, debuggable: D) -> Result<T, OofBuilder> {
match self {
Some(t) => Ok(t),
None => Err(OofBuilder::new().with_attachment(debuggable)),
}
}
#[cfg_attr(feature = "location", track_caller)]
fn _attach_lazy<D: ToString, F: FnOnce() -> D>(self, f: F) -> Result<T, OofBuilder> {
match self {
Some(t) => Ok(t),
None => Err(OofBuilder::new().with_attachment_lazy(f)),
}
}
}