Diffstat (limited to 'src/walk.rs')
-rw-r--r--src/walk.rs34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/walk.rs b/src/walk.rs
index a119965..32232fd 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -8,7 +8,7 @@ use crate::{
};
/// A type that can be walked.
-pub trait Walk<'ctx>: WalkerTypes<'ctx> + Sized {
+pub trait Walk<'ctx>: WalkerTypes + Sized {
/// The walker for the type.
type Walker<E: Effect<'ctx>>: Walker<
'ctx,
@@ -20,7 +20,7 @@ pub trait Walk<'ctx>: WalkerTypes<'ctx> + Sized {
fn into_walker<E: Effect<'ctx>>(self) -> Self::Walker<E>;
}
-pub trait WalkerTypes<'ctx> {
+pub trait WalkerTypes {
type Error: Send;
/// An arbitrary type the walker is left with after walking.
@@ -38,7 +38,7 @@ pub trait WalkerTypes<'ctx> {
/// - 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>: WalkerTypes<'ctx> + Send {
+pub trait Walker<'ctx>: WalkerTypes + Send {
type Effect: Effect<'ctx>;
/// Walk the value.
@@ -52,7 +52,7 @@ pub trait Walker<'ctx>: WalkerTypes<'ctx> + Send {
Self: 'a;
}
-pub trait DynWalker<'ctx>: Send {
+pub trait WalkerObjSafe<'ctx>: Send {
type Effect: Effect<'ctx>;
fn walk<'a>(
@@ -61,15 +61,20 @@ pub trait DynWalker<'ctx>: Send {
) -> Future<'a, 'ctx, ControlFlow<(), ()>, Self::Effect>
where
Self: 'a;
+
+ fn skip(&mut self);
}
-enum DynWalkerState<'ctx, W: WalkerTypes<'ctx>> {
+pub type DynWalker<'a, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'ctx, Effect = E> + Send + 'a);
+
+enum DynWalkerState<W: WalkerTypes> {
+ Skipped,
Walking,
Pending(W),
Done(Result<W::Output, W::Error>),
}
-pub enum DynWalkerError<'ctx, W: WalkerTypes<'ctx>> {
+pub enum DynWalkerError<W: WalkerTypes> {
NeverWalked(W),
/// This can only happen if a panic happens furing the walk and is then caught before calling
@@ -79,27 +84,28 @@ pub enum DynWalkerError<'ctx, W: WalkerTypes<'ctx>> {
Walker(W::Error),
}
-pub struct DynWalkerAdapter<'ctx, W: WalkerTypes<'ctx>> {
- state: DynWalkerState<'ctx, W>,
+pub struct DynWalkerAdapter<W: WalkerTypes> {
+ state: DynWalkerState<W>,
}
-impl<'ctx, W: WalkerTypes<'ctx>> DynWalkerAdapter<'ctx, W> {
+impl<W: WalkerTypes> DynWalkerAdapter<W> {
pub fn new(walker: W) -> Self {
Self {
state: DynWalkerState::Pending(walker),
}
}
- pub fn finish(self) -> Result<W::Output, DynWalkerError<'ctx, W>> {
+ pub fn finish(self) -> Result<Option<W::Output>, DynWalkerError<W>> {
match self.state {
+ DynWalkerState::Skipped => Ok(None),
DynWalkerState::Walking => Err(DynWalkerError::WalkNeverFinished),
DynWalkerState::Pending(walker) => Err(DynWalkerError::NeverWalked(walker)),
- DynWalkerState::Done(result) => result.map_err(DynWalkerError::Walker),
+ DynWalkerState::Done(result) => result.map(Some).map_err(DynWalkerError::Walker),
}
}
}
-impl<'ctx, W: Walker<'ctx>> DynWalker<'ctx> for DynWalkerAdapter<'ctx, W> {
+impl<'ctx, W: Walker<'ctx>> WalkerObjSafe<'ctx> for DynWalkerAdapter<W> {
type Effect = W::Effect;
fn walk<'a>(
@@ -121,4 +127,8 @@ impl<'ctx, W: Walker<'ctx>> DynWalker<'ctx> for DynWalkerAdapter<'ctx, W> {
ControlFlow::Continue(())
})
}
+
+ fn skip(&mut self) {
+ self.state = DynWalkerState::Skipped;
+ }
}