Diffstat (limited to 'src/protocol/visitor/sequence.rs')
-rw-r--r--src/protocol/visitor/sequence.rs62
1 files changed, 34 insertions, 28 deletions
diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs
index a3ca785..8c7b2e4 100644
--- a/src/protocol/visitor/sequence.rs
+++ b/src/protocol/visitor/sequence.rs
@@ -1,23 +1,19 @@
-use core::ops::ControlFlow;
-
use crate::{
effect::{Effect, Future},
higher_ranked_type,
hkt::AnySend,
nameable,
- protocol::{walker::hint::HintMeta, Visitor}, Flow, never::Never,
+ protocol::{walker::hint::HintMeta, Visitor},
+ Flow,
};
-pub trait Sequence<'ctx> {
- type Effect: Effect<'ctx>;
+use super::Status;
- fn visit<'a>(
- &'a mut self,
- scope: DynSequenceScope<'a, 'ctx, Self::Effect>,
- ) -> Future<'a, 'ctx, Flow<Never>, Self::Effect>;
+pub trait Sequence<'ctx, E: Effect<'ctx>> {
+ fn visit<'a>(&'a mut self, scope: DynSequenceScope<'a, 'ctx, E>) -> Future<'a, 'ctx, Flow, E>;
}
-pub type DynSequence<'a, 'ctx, E> = dyn Sequence<'ctx, Effect = E> + Send + 'a;
+pub type DynSequence<'a, 'ctx, E> = dyn Sequence<'ctx, E> + Send + 'a;
nameable! {
pub struct Name['a, 'ctx, E];
@@ -33,27 +29,13 @@ nameable! {
}
}
-pub trait SequenceScope<'ctx> {
- type Effect: Effect<'ctx>;
-
- fn size_hint<'a>(
- &'a mut self,
- ) -> Future<'a, 'ctx, (usize, Option<usize>), Self::Effect>;
+pub trait SequenceScope<'ctx, E: Effect<'ctx>> {
+ fn size_hint<'a>(&'a mut self) -> Future<'a, 'ctx, (usize, Option<usize>), E>;
- fn next<'a>(
- &'a mut self,
- visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, SequenceFlow, Self::Effect>;
+ fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E>;
}
-pub type DynSequenceScope<'a, 'ctx, E> = &'a mut (dyn SequenceScope<'ctx, Effect = E> + Send + 'a);
-
-#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
-pub enum SequenceFlow {
- Done,
- Continue,
- Break,
-}
+pub type DynSequenceScope<'a, 'ctx, E> = &'a mut (dyn SequenceScope<'ctx, E> + Send + 'a);
higher_ranked_type! {
pub type KnownHkt['ctx]: (AnySend) = for<'lt> Known
@@ -73,3 +55,27 @@ impl<'a, 'ctx: 'a, E: Effect<'ctx>> HintMeta<'ctx> for DynSequence<'a, 'ctx, E>
type Hint = Hint;
}
+
+pub fn visit_sequence<'a, 'ctx, E: Effect<'ctx>>(
+ visitor: Visitor<'a, 'ctx>,
+ scope: DynSequenceScope<'a, 'ctx, E>,
+) -> Future<'a, 'ctx, Status, E> {
+ if let Some(object) = visitor.upcast_mut::<DynSequence<'_, 'ctx, E>>() {
+ // Allow the visitor to give a hint if it wants.
+ E::map(object.visit(scope), |flow| match flow {
+ Flow::Continue => {
+ // The visitor wants the walker to continue to it's normal
+ // walking.
+ Status::Continue
+ }
+ Flow::Break | Flow::Done => {
+ // The visitor is done (either because of an error or because
+ // it already used a hint).
+ Status::Break
+ }
+ })
+ } else {
+ // If the visitor doesn't support request hint then we continue.
+ E::ready(Status::Skipped)
+ }
+}