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