use ::alloc::borrow::Cow;
use crate::{
NeuErr,
error::ProvideContext,
features::{AnyDebugSendSync, ErrorSendSync},
};
pub trait NeuErrResultExt<T, M>: Sized {
#[track_caller]
fn context<C>(self, context: C) -> Result<T, NeuErr<ProvideContext>>
where
C: Into<Cow<'static, str>>;
#[track_caller]
fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr<ProvideContext>>
where
F: FnOnce() -> C,
C: Into<Cow<'static, str>>;
#[must_use]
fn attach<C>(self, context: C) -> Self
where
C: AnyDebugSendSync + 'static;
#[must_use]
fn attach_with<F, C>(self, context_fn: F) -> Self
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static;
#[must_use]
fn attach_override<C>(self, context: C) -> Self
where
C: AnyDebugSendSync + 'static;
#[must_use]
fn attach_override_with<F, C>(self, context_fn: F) -> Self
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static;
}
impl<T, M> NeuErrResultExt<T, M> for Result<T, NeuErr<M>> {
#[track_caller]
fn context<C>(self, context: C) -> Result<T, NeuErr<ProvideContext>>
where
C: Into<Cow<'static, str>>,
{
match self {
Ok(value) => Ok(value),
Err(err) => Err(err.context(context)),
}
}
#[track_caller]
fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr<ProvideContext>>
where
F: FnOnce() -> C,
C: Into<Cow<'static, str>>,
{
match self {
Ok(value) => Ok(value),
Err(err) => Err(err.context(context_fn())),
}
}
fn attach<C>(self, context: C) -> Self
where
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| err.attach(context))
}
fn attach_with<F, C>(self, context_fn: F) -> Self
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| err.attach(context_fn()))
}
fn attach_override<C>(self, context: C) -> Self
where
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| err.attach_override(context))
}
fn attach_override_with<F, C>(self, context_fn: F) -> Self
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| err.attach_override(context_fn()))
}
}
pub trait ConvertResult<T, E>: Sized {
#[track_caller]
fn context<C>(self, context: C) -> Result<T, NeuErr<ProvideContext>>
where
C: Into<Cow<'static, str>>;
#[track_caller]
fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr<ProvideContext>>
where
F: FnOnce(&E) -> C,
C: Into<Cow<'static, str>>;
fn attach<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static;
fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce(&E) -> C,
C: AnyDebugSendSync + 'static;
fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static;
fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce(&E) -> C,
C: AnyDebugSendSync + 'static;
}
impl<T, E> ConvertResult<T, E> for Result<T, E>
where
E: ErrorSendSync + 'static,
{
#[track_caller]
fn context<C>(self, context: C) -> Result<T, NeuErr<ProvideContext>>
where
C: Into<Cow<'static, str>>,
{
match self {
Ok(value) => Ok(value),
Err(err) => Err(NeuErr::from_source(err).context(context)),
}
}
#[track_caller]
fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr<ProvideContext>>
where
F: FnOnce(&E) -> C,
C: Into<Cow<'static, str>>,
{
match self {
Ok(value) => Ok(value),
Err(err) => {
let context = context_fn(&err);
Err(NeuErr::from_source(err).context(context))
}
}
}
fn attach<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| NeuErr::from_source(err).attach(context))
}
fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce(&E) -> C,
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| {
let attach = context_fn(&err);
NeuErr::from_source(err).attach(attach)
})
}
fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| NeuErr::from_source(err).attach_override(context))
}
fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce(&E) -> C,
C: AnyDebugSendSync + 'static,
{
self.map_err(|err| {
let attach = context_fn(&err);
NeuErr::from_source(err).attach_override(attach)
})
}
}
pub trait ConvertOption<T>: Sized {
#[track_caller]
fn context<C>(self, context: C) -> Result<T, NeuErr<ProvideContext>>
where
C: Into<Cow<'static, str>>;
#[track_caller]
fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr<ProvideContext>>
where
F: FnOnce() -> C,
C: Into<Cow<'static, str>>;
fn attach<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static;
fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static;
fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static;
fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static;
}
impl<T> ConvertOption<T> for Option<T> {
#[track_caller]
fn context<C>(self, context: C) -> Result<T, NeuErr<ProvideContext>>
where
C: Into<Cow<'static, str>>,
{
match self {
Some(value) => Ok(value),
None => Err(NeuErr::new(context)),
}
}
#[track_caller]
fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr<ProvideContext>>
where
F: FnOnce() -> C,
C: Into<Cow<'static, str>>,
{
match self {
Some(value) => Ok(value),
None => {
let context = context_fn();
Err(NeuErr::new(context))
}
}
}
fn attach<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static,
{
self.ok_or_else(|| NeuErr::default().attach(context))
}
fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static,
{
self.ok_or_else(|| {
let attach = context_fn();
NeuErr::default().attach(attach)
})
}
fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
where
C: AnyDebugSendSync + 'static,
{
self.ok_or_else(|| NeuErr::default().attach_override(context))
}
fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
where
F: FnOnce() -> C,
C: AnyDebugSendSync + 'static,
{
self.ok_or_else(|| {
let attach = context_fn();
NeuErr::default().attach_override(attach)
})
}
}
pub trait ResultExt<T, E> {
fn or_collect<C>(self, collection: &mut C) -> Option<T>
where
C: Extend<E>;
}
impl<T, E> ResultExt<T, E> for Result<T, E> {
fn or_collect<C>(self, collection: &mut C) -> Option<T>
where
C: Extend<E>,
{
match self {
Ok(value) => Some(value),
Err(err) => {
collection.extend(core::iter::once(err));
None
}
}
}
}