use std::borrow;
use std::error;
use std::result;
use super::CloneableError;
use super::Error;
use super::ErrorClone;
use super::Result;
type CowStr = borrow::Cow<'static, str>;
pub trait ResultLiquidChainExt<T> {
#[must_use]
fn chain<S: Into<CowStr>>(self, msg: S) -> Result<T>;
#[must_use]
fn chain_with<F>(self, msg: F) -> Result<T>
where
F: FnOnce() -> CowStr;
}
pub trait ResultLiquidReplaceExt<T> {
#[must_use]
fn lossy_chain<S: Into<CowStr>>(self, msg: S) -> Result<T>;
#[must_use]
fn lossy_chain_with<F>(self, msg: F) -> Result<T>
where
F: FnOnce() -> CowStr;
#[must_use]
fn replace<S: Into<CowStr>>(self, msg: S) -> Result<T>;
#[must_use]
fn replace_with<F>(self, msg: F) -> Result<T>
where
F: FnOnce() -> CowStr;
}
impl<T, E> ResultLiquidChainExt<T> for result::Result<T, E>
where
E: ErrorClone,
{
fn chain<S: Into<CowStr>>(self, msg: S) -> Result<T> {
self.map_err(|err| Error::with_msg(msg).cause(err))
}
fn chain_with<F>(self, msg: F) -> Result<T>
where
F: FnOnce() -> CowStr,
{
self.map_err(|err| Error::with_msg(msg()).cause(err))
}
}
impl<T, E> ResultLiquidReplaceExt<T> for result::Result<T, E>
where
E: error::Error + Send + Sync + 'static,
{
fn lossy_chain<S: Into<CowStr>>(self, msg: S) -> Result<T> {
self.map_err(|err| Error::with_msg(msg).cause(CloneableError::new(err)))
}
fn lossy_chain_with<F>(self, msg: F) -> Result<T>
where
F: FnOnce() -> CowStr,
{
self.map_err(|err| Error::with_msg(msg()).cause(CloneableError::new(err)))
}
fn replace<S: Into<CowStr>>(self, msg: S) -> Result<T> {
self.map_err(|_| Error::with_msg(msg))
}
fn replace_with<F>(self, msg: F) -> Result<T>
where
F: FnOnce() -> CowStr,
{
self.map_err(|_| Error::with_msg(msg()))
}
}
pub trait ResultLiquidExt<T>
where
Self: ::std::marker::Sized,
{
#[must_use]
fn trace<S>(self, trace: S) -> Result<T>
where
S: Into<CowStr>;
#[must_use]
fn trace_with<F>(self, trace: F) -> Result<T>
where
F: FnOnce() -> CowStr;
#[must_use]
fn context_key<S>(self, key: S) -> Key<T>
where
S: Into<CowStr>;
#[must_use]
fn context_key_with<F>(self, key: F) -> FnKey<T, F>
where
F: FnOnce() -> CowStr;
}
impl<T> ResultLiquidExt<T> for Result<T> {
fn trace<S>(self, trace: S) -> Result<T>
where
S: Into<CowStr>,
{
self.map_err(|err| err.trace(trace))
}
fn trace_with<F>(self, trace: F) -> Result<T>
where
F: FnOnce() -> CowStr,
{
self.map_err(|err| err.trace(trace()))
}
fn context_key<S>(self, key: S) -> Key<T>
where
S: Into<CowStr>,
{
Key::new(self, key)
}
fn context_key_with<F>(self, key: F) -> FnKey<T, F>
where
F: FnOnce() -> CowStr,
{
FnKey::new(self, key)
}
}
#[allow(missing_debug_implementations)]
pub struct Key<T> {
builder: Result<T>,
key: CowStr,
}
impl<T> Key<T> {
#[must_use]
pub fn new<S>(builder: Result<T>, key: S) -> Self
where
S: Into<CowStr>,
{
Self {
builder,
key: key.into(),
}
}
#[must_use]
pub fn value<S>(self, value: S) -> Result<T>
where
S: Into<CowStr>,
{
let builder = self.builder;
let key = self.key;
builder.map_err(|err| err.context(key, value.into()))
}
#[must_use]
pub fn value_with<F>(self, value: F) -> Result<T>
where
F: FnOnce() -> CowStr,
{
let builder = self.builder;
let key = self.key;
builder.map_err(|err| err.context(key, value()))
}
}
#[allow(missing_debug_implementations)]
pub struct FnKey<T, F>
where
F: FnOnce() -> CowStr,
{
builder: Result<T>,
key: F,
}
impl<T, F> FnKey<T, F>
where
F: FnOnce() -> CowStr,
{
#[must_use]
pub fn new(builder: Result<T>, key: F) -> Self {
Self { builder, key }
}
#[must_use]
pub fn value<S>(self, value: S) -> Result<T>
where
S: Into<CowStr>,
{
let builder = self.builder;
let key = self.key;
builder.map_err(|err| err.context((key)(), value.into()))
}
#[must_use]
pub fn value_with<V>(self, value: V) -> Result<T>
where
V: FnOnce() -> CowStr,
{
let builder = self.builder;
let key = self.key;
builder.map_err(|err| err.context((key)(), value()))
}
}