Diffstat (limited to 'src/protocol/visitor.rs')
-rw-r--r--src/protocol/visitor.rs125
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),
)
}
}