Diffstat (limited to 'src/walk.rs')
| -rw-r--r-- | src/walk.rs | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/src/walk.rs b/src/walk.rs index 692c963..10f96cd 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -2,19 +2,20 @@ pub mod walkers; use core::fmt::Debug; +use effectful::{bound::{IsSend, IsSync}, environment::{DynBind, Environment, NativeForm}}; + use crate::{ - effect::{Effect, Effective, EffectiveExt, ErasedEffective}, protocol::DynVisitor, Flow, }; /// A type that can be walked. -pub trait Walk<'ctx, M, E: Effect>: Sized { +pub trait Walk<'ctx, M, E: Environment>: Sized { /// The walker for the type. type Walker: Walker<'ctx, E>; #[must_use] - fn into_walker<'e>(self) -> ErasedEffective<'e, Self::Walker, E> + fn into_walker<'e>(self) -> NativeForm<'e, Self::Walker, E> where Self: 'e; } @@ -28,44 +29,44 @@ pub trait Walk<'ctx, M, E: Effect>: 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: Effect>: Send + Sync { - type Error: Send + Sync + Debug; +pub trait Walker<'ctx, E: Environment>: DynBind<E> { + type Error: DynBind<E> + Debug; /// An arbitrary type the walker is left with after walking. /// /// Its recommended that this is `Self` if the walker is repeatable. - type Output: Send + Sync; + type Output: DynBind<E>; /// Walk the value. /// /// The walker should send data to the `visitor` as it walks the value. fn walk<'visitor: 'effect, 'effect>( self, - visitor: DynVisitor<'visitor, 'ctx>, - ) -> ErasedEffective<'effect, Result<Self::Output, Self::Error>, E> + visitor: DynVisitor<'visitor, 'ctx, E>, + ) -> NativeForm<'effect, Result<Self::Output, Self::Error>, E> where Self: 'effect; } -pub trait WalkerObjSafe<'ctx, E: Effect>: Send { +pub trait WalkerObjSafe<'ctx, E: Environment>: DynBind<E> { fn walk<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Flow, E> + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Flow, E> where Self: 'a; } -pub type DynWalkerObjSafe<'a, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'ctx, E> + Send + Sync + 'a); +pub type DynWalkerObjSafe<'a, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'ctx, E> + 'a); -enum DynWalkerState<'ctx, W: Walker<'ctx, E>, E: Effect> { +enum DynWalkerState<'ctx, W: Walker<'ctx, E>, E: Environment> { Walking, Pending(W), Done(W::Output), Err(W::Error), } -pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Effect> { +pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Environment> { NeverWalked(W), /// This can only happen if a panic happens furing the walk and is then caught before calling @@ -77,11 +78,15 @@ pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Effect> { WasWalked(W::Output), } -pub struct DynWalkerAdapter<'ctx, W: Walker<'ctx, E>, E: Effect> { +pub struct DynWalkerAdapter<'ctx, W: Walker<'ctx, E>, E: Environment> { state: DynWalkerState<'ctx, W, E>, } -impl<'ctx, W: Walker<'ctx, E>, E: Effect> DynWalkerAdapter<'ctx, W, E> { +unsafe impl<'ctx, W: Walker<'ctx, E>, E: Environment> IsSend<E::NeedSend> for DynWalkerAdapter<'ctx, W, E> {} + +unsafe impl<'ctx, W: Walker<'ctx, E>, E: Environment> IsSync<E::NeedSync> for DynWalkerAdapter<'ctx, W, E> {} + +impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> { #[inline(always)] pub fn new(walker: W) -> Self { Self { @@ -110,20 +115,20 @@ impl<'ctx, W: Walker<'ctx, E>, E: Effect> DynWalkerAdapter<'ctx, W, E> { } } -impl<'ctx, W: Walker<'ctx, E>, E: Effect> WalkerObjSafe<'ctx, E> for DynWalkerAdapter<'ctx, W, E> { +impl<'ctx, W: Walker<'ctx, E>, E: Environment> WalkerObjSafe<'ctx, E> for DynWalkerAdapter<'ctx, W, E> { #[inline(always)] fn walk<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Flow, E> + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Flow, E> where Self: 'a, { if let DynWalkerState::Pending(walker) = core::mem::replace(&mut self.state, DynWalkerState::Walking) { - E::ready((self, visitor)) - .as_ctx(|(this, visitor)| { + E::value((self, visitor)) + .update(|(this, visitor)| { // Walk the walker. walker .walk(visitor.cast()) @@ -143,9 +148,10 @@ impl<'ctx, W: Walker<'ctx, E>, E: Effect> WalkerObjSafe<'ctx, E> for DynWalkerAd .cast() }) .map(|(_, value)| value) + .cast() } else { // Can't do anything if the walker has already been walked. - E::ready(Flow::Done) + E::value(Flow::Done).cast() } } } |