Diffstat (limited to 'src/walk.rs')
-rw-r--r--src/walk.rs121
1 files changed, 57 insertions, 64 deletions
diff --git a/src/walk.rs b/src/walk.rs
index 1c56ad5..9ba482d 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -9,14 +9,14 @@ use effectful::{
use crate::{protocol::DynVisitor, Flow};
/// A type that can be walked.
-pub trait Walk<'ctx, M, E: Environment>: Sized {
+pub trait Walk<'src, M, E: Environment>: Sized {
/// The walker for the type.
- type Walker: Walker<'ctx, E>;
+ type Walker: Walker<'src, E>;
#[must_use]
- fn into_walker<'e>(self) -> Canonical<'e, Self::Walker, E>
+ fn into_walker<'u>(self) -> Canonical<'u, Self::Walker, E>
where
- Self: 'e;
+ Self: 'u;
}
/// Walker for a type.
@@ -28,7 +28,7 @@ pub trait Walk<'ctx, M, E: Environment>: Sized {
/// - Call [From::from()] with a value to be walked to make a walker.
/// - Call [Self::walk()] to walk the value. Data will be sent to the provided
/// visitor.
-pub trait Walker<'ctx, E: Environment>: DynBind<E> {
+pub trait Walker<'src, E: Environment>: DynBind<E> {
type Error: DynBind<E> + Debug;
/// An arbitrary type the walker is left with after walking.
@@ -39,35 +39,32 @@ pub trait Walker<'ctx, E: Environment>: DynBind<E> {
/// Walk the value.
///
/// The walker should send data to the `visitor` as it walks the value.
- fn walk<'visitor: 'effect, 'lt: 'effect, 'effect>(
+ fn walk<'r>(
self,
- visitor: DynVisitor<'visitor, 'lt, 'ctx, E>,
- ) -> Canonical<'effect, Result<Self::Output, Self::Error>, E>
+ visitor: DynVisitor<'r, 'src, E>,
+ ) -> Canonical<'r, Result<Self::Output, Self::Error>, E>
where
- Self: 'effect;
+ Self: 'r;
}
-pub trait WalkerObjSafe<'lt, 'ctx: 'lt, E: Environment>: DynBind<E> + 'lt {
- fn walk<'a, 'b: 'c, 'd: 'b, 'c>(
- &'a mut self,
- visitor: DynVisitor<'b, 'd, 'ctx, E>,
- ) -> Canonical<'c, Flow, E>
- where
- 'ctx: 'd,
- Self: 'a;
+pub trait WalkerObjSafe<'src, E: Environment>: DynBind<E> {
+ fn walk<'r>(
+ &'r mut self,
+ visitor: DynVisitor<'r, 'src, E>,
+ ) -> Canonical<'r, Flow, E>;
}
-pub type DynWalkerObjSafe<'a, 'lt, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'lt, 'ctx, E> + 'lt);
+pub type DynWalkerObjSafe<'r, 'src, E> = &'r mut dyn WalkerObjSafe<'src, E>;
#[derive(SendSync)]
-enum DynWalkerState<'ctx, W: Walker<'ctx, E>, E: Environment> {
+enum DynWalkerState<'src, W: Walker<'src, E>, E: Environment> {
Walking,
Pending(W),
Done(W::Output),
Err(W::Error),
}
-pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Environment> {
+pub enum DynWalkerError<'src, W: Walker<'src, E>, E: Environment> {
NeverWalked(W),
/// This can only happen if a panic happens furing the walk and is then caught before calling
@@ -80,11 +77,11 @@ pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Environment> {
}
#[derive(SendSync)]
-pub struct DynWalkerAdapter<'ctx, W: Walker<'ctx, E>, E: Environment> {
- state: DynWalkerState<'ctx, W, E>,
+pub struct DynWalkerAdapter<'src, W: Walker<'src, E>, E: Environment> {
+ state: DynWalkerState<'src, W, E>,
}
-impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> {
+impl<'src, W: Walker<'src, E>, E: Environment> DynWalkerAdapter<'src, W, E> {
#[inline(always)]
pub fn new(walker: W) -> Self {
Self {
@@ -93,7 +90,7 @@ impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> {
}
#[inline(always)]
- pub fn finish(self) -> Result<W::Output, DynWalkerError<'ctx, W, E>> {
+ pub fn finish(self) -> Result<W::Output, DynWalkerError<'src, W, E>> {
match self.state {
DynWalkerState::Walking => Err(DynWalkerError::WalkNeverFinished),
DynWalkerState::Pending(walker) => Err(DynWalkerError::NeverWalked(walker)),
@@ -103,7 +100,7 @@ impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> {
}
#[inline(always)]
- pub fn into_inner(self) -> Result<W, DynWalkerError<'ctx, W, E>> {
+ pub fn into_inner(self) -> Result<W, DynWalkerError<'src, W, E>> {
match self.state {
DynWalkerState::Walking => Err(DynWalkerError::WalkNeverFinished),
DynWalkerState::Pending(walker) => Ok(walker),
@@ -113,48 +110,44 @@ impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> {
}
}
-impl<'lt, 'ctx: 'lt, W: Walker<'ctx, E> + 'lt, E: Environment> WalkerObjSafe<'lt, 'ctx, E>
- for DynWalkerAdapter<'ctx, W, E>
+impl<'src, W: Walker<'src, E>, E: Environment> WalkerObjSafe<'src, E>
+ for DynWalkerAdapter<'src, W, E>
where
Self: DynBind<E>,
{
#[inline(always)]
- fn walk<'a, 'b: 'c, 'd: 'b, 'c>(
- &'a mut self,
- visitor: DynVisitor<'b, 'd, 'ctx, E>,
- ) -> Canonical<'c, Flow, E>
- where
- Self: 'a,
- {
- todo!()
- // if let DynWalkerState::Pending(walker) =
- // core::mem::replace(&mut self.state, DynWalkerState::Walking)
- // {
- // E::value((self, visitor))
- // .update_map(walker, |walker, (this, visitor)| {
- // // Walk the walker.
- // walker
- // .walk(visitor.cast())
- // .map(this, |this, value| match value {
- // Ok(value) => {
- // this.state = DynWalkerState::Done(value);
- // Flow::Done
- // }
- // Err(err) => {
- // this.state = DynWalkerState::Err(err);
- //
- // // Signal that control flow should stop as soon as possible as we
- // // are in an error state.
- // Flow::Err
- // }
- // })
- // .cast()
- // })
- // .map((), |_, (_, value)| value)
- // .cast()
- // } else {
- // // Can't do anything if the walker has already been walked.
- // E::value(Flow::Done).cast()
- // }
+ fn walk<'r>(
+ &'r mut self,
+ visitor: DynVisitor<'r, 'src, E>,
+ ) -> Canonical<'r, Flow, E>{
+ if let DynWalkerState::Pending(walker) =
+ core::mem::replace(&mut self.state, DynWalkerState::Walking)
+ {
+ E::value((self, visitor))
+ .update_map(walker, |walker, (this, visitor)| {
+ // Walk the walker.
+ walker
+ .walk(visitor.cast())
+ .map(this, |this, value| match value {
+ Ok(value) => {
+ this.state = DynWalkerState::Done(value);
+ Flow::Done
+ }
+ Err(err) => {
+ this.state = DynWalkerState::Err(err);
+
+ // Signal that control flow should stop as soon as possible as we
+ // are in an error state.
+ Flow::Err
+ }
+ })
+ .cast()
+ })
+ .map((), |_, (_, value)| value)
+ .cast()
+ } else {
+ // Can't do anything if the walker has already been walked.
+ E::value(Flow::Done).cast()
+ }
}
}