Diffstat (limited to 'src/effect.rs')
| -rw-r--r-- | src/effect.rs | 52 |
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, |