Diffstat (limited to 'src/walk.rs')
| -rw-r--r-- | src/walk.rs | 121 |
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() + } } } |