Diffstat (limited to 'src/walk/walkers/core/key_value.rs')
| -rw-r--r-- | src/walk/walkers/core/key_value.rs | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/src/walk/walkers/core/key_value.rs b/src/walk/walkers/core/key_value.rs index 3c0f700..1adb7b1 100644 --- a/src/walk/walkers/core/key_value.rs +++ b/src/walk/walkers/core/key_value.rs @@ -1,16 +1,20 @@ use core::marker::PhantomData; use crate::{ - effect::{all_ctx, merge_ctx, Effect, Effective, ErasedEffective}, + effect::{Effect, EffectExt as _, Effective, EffectiveExt as _, ErasedEffective}, never::Never, protocol::{ - visitor::{visit_tag, TagConst, TagError, TagKind, VisitResult}, + visitor::{ + tags, visit_tag, EffectiveVisitExt as _, TagConst, TagError, TagKind, VisitResult, + }, DynVisitor, }, walkers::core::noop::NoopWalker, Flow, WalkerTypes, TAG_KEY, TAG_KEY_VALUE, TAG_VALUE, }; +use super::value::ValueWalker; + pub struct KeyValueWalker<T, K, V> { key_walker: K, value_walker: V, @@ -53,7 +57,7 @@ impl<'ctx, T, K, V, E> crate::Walker<'ctx, E> for KeyValueWalker<T, K, V> where E: Effect, T: TagKind, - K: crate::Walker<'ctx, E>, + K: crate::Walker<'ctx, E> + 'ctx, V: crate::Walker<'ctx, E> + 'ctx, { #[inline(always)] @@ -61,22 +65,38 @@ where self, visitor: DynVisitor<'b, 'ctx>, ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> { - E::ready(visitor) - .as_ctx( - all_ctx, - move |visitor, _| { - self.value_walker - .walk(visitor.cast()) - .map(|result| match result { - Ok(_) => Ok::<_, Self::Error>(()), - Err(_err) => todo!(), - }) - .into_erased() - }, - merge_ctx, - ) - .map(|(_, value)| value) - .into_erased() + let Self { + key_walker, + value_walker, + tag, + } = self; + + E::as_ctx( + visitor, + #[inline(always)] + |visitor| { + visit_tag::<tags::Key, E, _>(TagConst, visitor.cast(), key_walker) + .map(|result| match result { + Ok(visit) => visit.unit_skipped(), + Err(_) => Flow::Err.into(), + }) + .cast() + }, + ) + .if_not_finished( + #[inline(always)] + |visitor| { + value_walker + .walk(visitor.cast()) + .map(|result| match result { + Ok(_) => Flow::Done.into(), + Err(_err) => Flow::Err.into(), + }) + .cast() + }, + ) + .remove_ctx() + .map(|visit| Ok(())) // E::wrap(async move { // match visit_tag::<T, E, _>(self.tag, visitor.cast(), NoopWalker::new()).await { |