Diffstat (limited to 'src/effect.rs')
-rw-r--r--src/effect.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/effect.rs b/src/effect.rs
index 0b1a76b..f39f777 100644
--- a/src/effect.rs
+++ b/src/effect.rs
@@ -210,6 +210,19 @@ impl<T, E> ShortCircuit for Result<T, E> {
}
}
+pub trait ResultErrorExt<E> {
+ fn into_error(self) -> E;
+}
+
+impl<E> ResultErrorExt<E> for Result<Never, E> {
+ fn into_error(self) -> E {
+ match self {
+ Ok(_) => unreachable!(),
+ Err(err) => err,
+ }
+ }
+}
+
#[macro_export]
macro_rules! tri {
($expr:expr $(,)?) => {
@@ -424,6 +437,45 @@ pub trait EffectiveExt<'lt>: Effective<'lt> {
)
}
+ fn or_else_update<'ctx, 'wrap, Ctx, U, F>(
+ self,
+ f: F,
+ ) -> ErasedEffective<'wrap, (Ctx, U), Self::Effect>
+ where
+ Self: Effective<'lt, Output = (Ctx, U)>,
+ F: 'wrap
+ + for<'temp> FnOnce(
+ &'temp mut Ctx,
+ U::Short,
+ ) -> ErasedEffective<'temp, U, Self::Effect, &'ctx ()>,
+ U: ShortCircuit,
+ U::Short: Ss,
+ Ctx: Ss,
+ U: Ss,
+ F: Ss,
+ 'ctx: 'lt,
+ 'lt: 'wrap,
+ {
+ self.r#do(
+ |(ctx, v)| {
+ (
+ ctx,
+ // The inverting of the control flow is because on breaks we want to run the
+ // function not skip it.
+ match U::branch(v) {
+ ControlFlow::Continue(v) => ControlFlow::Break(U::from_output(v)),
+ ControlFlow::Break(v) => ControlFlow::Continue(v),
+ },
+ )
+ },
+ |ctx, v| f(ctx, v).cast(),
+ |_, v| ControlFlow::<_, Never>::Break(v),
+ |_, _| unreachable!(),
+ |_, _, _: Never| unreachable!(),
+ |ctx, _, v| (ctx, v),
+ )
+ }
+
#[allow(clippy::wrong_self_convention)]
fn as_ctx_or_else_map<'ctx, 'wrap, Ctx, U, F>(
self,