Diffstat (limited to 'src/protocol/visitor.rs')
| -rw-r--r-- | src/protocol/visitor.rs | 125 |
1 files changed, 70 insertions, 55 deletions
diff --git a/src/protocol/visitor.rs b/src/protocol/visitor.rs index 0189dc1..5916235 100644 --- a/src/protocol/visitor.rs +++ b/src/protocol/visitor.rs @@ -1,9 +1,6 @@ use core::ops::ControlFlow; -use crate::{ - never::Never, - Flow, Status, -}; +use crate::{never::Never, Flow, Status}; mod recoverable; mod request_hint; @@ -11,7 +8,13 @@ mod sequence; mod tag; mod value; -use effectful::{effective::Effective, environment::{DynBind, NativeForm}, forward_send_sync}; +use effectful::{ + bound::HasSendAndSync, + effective::{Effective, SplitUpdateEffective}, + environment::{DynBind, Environment, NativeForm}, + for_lt, forward_send_sync, + higher_ranked::Mut, +}; pub use recoverable::*; pub use request_hint::*; pub use sequence::*; @@ -94,71 +97,83 @@ impl<S> VisitResult<S> { } pub trait EffectiveVisitExt<'lt>: Effective<'lt> { - fn if_skipped<'ctx, 'wrap, Ctx, F>( + fn if_skipped<'ctx, 'wrap, Cap, Update>( self, - f: F, - ) -> NativeForm<'wrap, (Ctx, VisitResult<()>), Self::Env> + cap: Cap, + f: for<'a> fn(Cap, &'a mut Update) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, + ) -> SplitUpdateEffective< + 'wrap, + 'lt, + (), + ( + Cap, + HasSendAndSync< + for<'a> fn( + Cap, + &'a mut Update, + ) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, + >, + ), + Update, + VisitResult<()>, + VisitResult<()>, + Self, + > where - Ctx: DynBind<Self::Env>, - Self: Effective<'lt, Output = (Ctx, VisitResult<()>)>, - F: 'wrap - + for<'temp> FnOnce( - &'temp mut Ctx, - ) - -> NativeForm<'temp, VisitResult<()>, Self::Env, &'ctx ()>, + Cap: DynBind<Self::Env>, + Update: DynBind<Self::Env>, + Self: Effective<'lt, Output = (Update, VisitResult<()>)>, 'ctx: 'lt, 'lt: 'wrap, { - self.r#do( - |(ctx, v)| { - ( - ctx, - match v { - VisitResult::Skipped(()) => ControlFlow::Continue(()), - v => ControlFlow::Break(v), - }, - ) + self.split_update( + (), + |_, x| x, + (cap, HasSendAndSync(f)), + |(cap, HasSendAndSync(f)), update, value| match value { + VisitResult::Skipped(()) => f(cap, update), + _ => Self::Env::value(value).cast(), }, - |ctx, ()| f(ctx).cast(), - |_, v| ControlFlow::<_, Never>::Break(v), - |_, _| unreachable!(), - |_, _, _: Never| unreachable!(), - |ctx, _, v| (ctx, v), ) } - fn if_not_finished<'ctx, 'wrap, Ctx, F>( + fn if_not_finished<'ctx, 'wrap, Cap, Update>( self, - f: F, - ) -> NativeForm<'wrap, (Ctx, VisitResult<()>), Self::Env> + cap: Cap, + f: for<'a> fn(Cap, &'a mut Update) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, + ) -> SplitUpdateEffective< + 'wrap, + 'lt, + (), + ( + Cap, + HasSendAndSync< + for<'a> fn( + Cap, + &'a mut Update, + ) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, + >, + ), + Update, + VisitResult<()>, + VisitResult<()>, + Self, + > where - Ctx: DynBind<Self::Env>, - Self: Effective<'lt, Output = (Ctx, VisitResult<()>)>, - F: 'wrap - + for<'temp> FnOnce( - &'temp mut Ctx, - ) - -> NativeForm<'temp, VisitResult<()>, Self::Env, &'ctx ()>, + Cap: DynBind<Self::Env>, + Update: DynBind<Self::Env>, + Self: Effective<'lt, Output = (Update, VisitResult<()>)>, 'ctx: 'lt, 'lt: 'wrap, { - self.r#do( - |(ctx, v)| { - ( - ctx, - match v { - VisitResult::Skipped(()) | VisitResult::Control(Flow::Continue) => { - ControlFlow::Continue(()) - } - v => ControlFlow::Break(v), - }, - ) + self.split_update( + (), + |_, x| x, + (cap, HasSendAndSync(f)), + |(cap, HasSendAndSync(f)), update, value| match value { + VisitResult::Skipped(()) | VisitResult::Control(Flow::Continue) => f(cap, update), + _ => Self::Env::value(value).cast(), }, - |ctx, ()| f(ctx).cast(), - |_, v| ControlFlow::<_, Never>::Break(v), - |_, _| unreachable!(), - |_, _, _: Never| unreachable!(), - |ctx, _, v| (ctx, v), ) } } |