use super::{CellValue, MapExt, Watchable};
use crate::cell::{Cell, CellImmutable};
pub trait MapOkExt<T, E>: Watchable<Result<T, E>> {
#[track_caller]
fn map_ok<U, F>(&self, f: F) -> Cell<Result<U, E>, CellImmutable>
where
T: CellValue,
U: CellValue,
E: CellValue,
F: Fn(&T) -> U + Send + Sync + 'static,
Self: Clone + Send + Sync + 'static,
{
self.map(move |r| match r {
Ok(v) => Ok(f(v)),
Err(e) => Err(e.clone()),
})
}
}
impl<T, E, W> MapOkExt<T, E> for W
where
T: CellValue,
E: CellValue,
W: Watchable<Result<T, E>>,
{
}
pub trait MapErrExt<T, E>: Watchable<Result<T, E>> {
#[track_caller]
fn map_err<E2, F>(&self, f: F) -> Cell<Result<T, E2>, CellImmutable>
where
T: CellValue,
E: CellValue,
E2: CellValue,
F: Fn(&E) -> E2 + Send + Sync + 'static,
Self: Clone + Send + Sync + 'static,
{
self.map(move |r| match r {
Ok(v) => Ok(v.clone()),
Err(e) => Err(f(e)),
})
}
}
impl<T, E, W> MapErrExt<T, E> for W
where
T: CellValue,
E: CellValue,
W: Watchable<Result<T, E>>,
{
}
pub trait CatchErrorExt<T, E>: Watchable<Result<T, E>> {
#[track_caller]
fn catch_error<F>(&self, f: F) -> Cell<T, CellImmutable>
where
T: CellValue,
E: CellValue,
F: Fn(&E) -> T + Send + Sync + 'static,
Self: Clone + Send + Sync + 'static,
{
self.map(move |r| match r {
Ok(v) => v.clone(),
Err(e) => f(e),
})
}
}
impl<T, E, W> CatchErrorExt<T, E> for W
where
T: CellValue,
E: CellValue,
W: Watchable<Result<T, E>>,
{
}
pub trait UnwrapOrExt<T, E>: Watchable<Result<T, E>> {
#[track_caller]
fn unwrap_or(&self, default: T) -> Cell<T, CellImmutable>
where
T: CellValue,
E: CellValue,
Self: Clone + Send + Sync + 'static,
{
self.map(move |r| match r {
Ok(v) => v.clone(),
Err(_) => default.clone(),
})
}
#[track_caller]
fn unwrap_or_else<F>(&self, f: F) -> Cell<T, CellImmutable>
where
T: CellValue,
E: CellValue,
F: Fn(&E) -> T + Send + Sync + 'static,
Self: Clone + Send + Sync + 'static,
{
self.catch_error(f)
}
}
impl<T, E, W> UnwrapOrExt<T, E> for W
where
T: CellValue,
E: CellValue,
W: Watchable<Result<T, E>>,
{
}