use core::fmt::Display;
use super::Error;
use super::error::Trace;
mod private {
pub trait Sealed {}
}
use self::private::Sealed;
pub trait Context: Sealed {
fn module<D>(self, name: D) -> Self
where
D: Display,
Self: Sized;
fn with_module<D>(self, f: impl FnOnce() -> D) -> Self
where
D: Display;
fn trace(self, trace: Trace) -> Self;
fn with_trace(self, f: impl FnOnce() -> Trace) -> Self;
fn value<D>(self, name: D) -> Self
where
D: Display,
Self: Sized;
fn with_value<D>(self, f: impl FnOnce() -> D) -> Self
where
D: Display,
Self: Sized;
}
impl<T> Sealed for core::result::Result<T, Error> {}
impl<T> Context for core::result::Result<T, Error> {
fn module<D>(self, name: D) -> Self
where
D: Display,
Self: Sized,
{
self.with_module(|| name)
}
fn with_module<D>(self, f: impl FnOnce() -> D) -> Self
where
D: Display,
{
self.map_err(|mut e| {
e.trace.push_front(f());
e
})
}
fn trace(self, trace: Trace) -> Self {
self.with_trace(|| trace)
}
fn with_trace(self, f: impl FnOnce() -> Trace) -> Self {
self.map_err(|mut e| {
e.trace = f();
e
})
}
fn value<D>(self, name: D) -> Self
where
D: Display,
Self: Sized,
{
self.with_value(|| name)
}
fn with_value<D>(self, f: impl FnOnce() -> D) -> Self
where
D: Display,
Self: Sized,
{
self.map_err(|mut e| {
e.value.push_front(f());
e
})
}
}