use crate::exn::Exn;
pub trait ErrorExt: std::error::Error + Send + Sync + 'static {
#[track_caller]
fn raise(self) -> Exn<Self>
where
Self: Sized,
{
Exn::new(self)
}
#[track_caller]
fn and_raise<T: std::error::Error + Send + Sync + 'static>(self, context: T) -> Exn<T>
where
Self: Sized,
{
Exn::new(self).raise(context)
}
#[track_caller]
fn raise_erased(self) -> Exn
where
Self: Sized,
{
Exn::new(self).erased()
}
#[track_caller]
fn raise_all<T, I>(self, sources: I) -> Exn<Self>
where
Self: Sized,
T: std::error::Error + Send + Sync + 'static,
I: IntoIterator,
I::Item: Into<Exn<T>>,
{
Exn::raise_all(sources, self)
}
}
impl<T> ErrorExt for T where T: std::error::Error + Send + Sync + 'static {}
pub trait OptionExt {
type Some;
fn ok_or_raise<A, F>(self, err: F) -> Result<Self::Some, Exn<A>>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A;
fn ok_or_raise_erased<A, F>(self, err: F) -> Result<Self::Some, Exn>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A;
}
impl<T> OptionExt for Option<T> {
type Some = T;
#[track_caller]
fn ok_or_raise<A, F>(self, err: F) -> Result<T, Exn<A>>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A,
{
match self {
Some(v) => Ok(v),
None => Err(Exn::new(err())),
}
}
#[track_caller]
fn ok_or_raise_erased<A, F>(self, err: F) -> Result<T, Exn>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A,
{
self.ok_or_raise(err).map_err(Exn::erased)
}
}
pub trait ResultExt {
type Success;
type Error: std::error::Error + Send + Sync + 'static;
fn or_raise<A, F>(self, err: F) -> Result<Self::Success, Exn<A>>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A;
fn or_erased(self) -> Result<Self::Success, Exn>;
fn or_raise_erased<A, F>(self, err: F) -> Result<Self::Success, Exn>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A;
}
impl<T, E> ResultExt for Result<T, E>
where
E: std::error::Error + Send + Sync + 'static,
{
type Success = T;
type Error = E;
#[track_caller]
fn or_raise<A, F>(self, err: F) -> Result<Self::Success, Exn<A>>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A,
{
match self {
Ok(v) => Ok(v),
Err(e) => Err(Exn::new(e).raise(err())),
}
}
#[track_caller]
fn or_erased(self) -> Result<Self::Success, Exn> {
match self {
Ok(v) => Ok(v),
Err(e) => Err(Exn::new(e).erased()),
}
}
#[track_caller]
fn or_raise_erased<A, F>(self, err: F) -> Result<Self::Success, Exn>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A,
{
self.or_raise(err).map_err(Exn::erased)
}
}
impl<T, E> ResultExt for Result<T, Exn<E>>
where
E: std::error::Error + Send + Sync + 'static,
{
type Success = T;
type Error = E;
#[track_caller]
fn or_raise<A, F>(self, err: F) -> Result<Self::Success, Exn<A>>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A,
{
match self {
Ok(v) => Ok(v),
Err(e) => Err(e.raise(err())),
}
}
#[track_caller]
fn or_erased(self) -> Result<Self::Success, Exn> {
match self {
Ok(v) => Ok(v),
Err(e) => Err(e.erased()),
}
}
#[track_caller]
fn or_raise_erased<A, F>(self, err: F) -> Result<Self::Success, Exn>
where
A: std::error::Error + Send + Sync + 'static,
F: FnOnce() -> A,
{
self.or_raise(err).map_err(Exn::erased)
}
}