Diffstat (limited to 'src/walk/walkers/core/key_value.rs')
-rw-r--r--src/walk/walkers/core/key_value.rs58
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 {