use core::marker::PhantomData;
use crate::{
effect::{Adapters, Effect, ObjSafe},
never::Never,
protocol::{
visitor::{visit_tag, TagConst, TagError, TagKind, VisitResult},
DynVisitor,
},
walkers::core::noop::NoopWalker,
Flow, WalkerTypes, TAG_KEY, TAG_KEY_VALUE, TAG_VALUE,
};
pub struct KeyValueWalker<T, K, V> {
key_walker: K,
value_walker: V,
tag: T,
}
impl<T, K, V> KeyValueWalker<T, K, V> {
#[inline(always)]
pub fn new(tag: T, key_walker: K, value_walker: V) -> Self {
Self {
key_walker,
value_walker,
tag,
}
}
}
#[derive(Debug)]
#[allow(unused)]
enum KeyValueErrorKind<K, V> {
Tag(TagError<Never>),
Key(K),
Value(V),
}
#[derive(Debug)]
pub struct KeyValueError<K, V>(KeyValueErrorKind<K, V>);
impl<T, K, V> WalkerTypes for KeyValueWalker<T, K, V>
where
K: WalkerTypes,
V: WalkerTypes,
{
type Error = KeyValueError<K::Error, V::Error>;
type Output = ();
}
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>,
V: crate::Walker<'ctx, E> + 'ctx,
{
#[inline(always)]
fn walk<'b: 'c, 'c>(
self,
mut visitor: DynVisitor<'b, 'ctx>,
) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E> {
E::ready(visitor)
.as_ctx_for(move |visitor, _| {
(
self.value_walker
.walk(visitor.cast())
.map(|result| match result {
Ok(_) => Ok::<_, Self::Error>(()),
Err(_err) => todo!(),
})
.into(),
PhantomData,
)
})
.map(|(_, value)| value)
.into()
// E::wrap(async move {
// match visit_tag::<T, E, _>(self.tag, visitor.cast(), NoopWalker::new()).await {
// Ok(VisitResult::Skipped(_)) => {
// match visit_tag::<TagConst<{ TAG_KEY_VALUE.to_int() }>, E, _>(
// TagConst,
// visitor.cast(),
// NoopWalker::new(),
// )
// .await
// {
// Ok(VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue)) => {}
// Ok(VisitResult::Control(_flow)) => return Ok(()),
// Err(_) => todo!(),
// }
// }
// Ok(VisitResult::Control(Flow::Continue)) => {}
// Ok(VisitResult::Control(_flow)) => todo!(),
// Err(_) => todo!(),
// }
//
// match visit_tag::<TagConst<{ TAG_KEY.to_int() }>, E, _>(
// TagConst,
// visitor.cast(),
// self.key_walker,
// )
// .await
// {
// Ok(VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue)) => {}
// Ok(VisitResult::Control(_flow)) => return Ok(()),
// Err(_) => todo!(),
// }
//
// match visit_tag::<TagConst<{ TAG_VALUE.to_int() }>, E, _>(
// TagConst,
// visitor.cast(),
// self.value_walker,
// )
// .await
// {
// Ok(VisitResult::Control(Flow::Continue)) => {}
// Ok(VisitResult::Skipped(value_walker)) => {
// // Fallback to just walking the value.
// match value_walker.walk(visitor).await {
// Ok(_) => {}
// Err(_err) => todo!(),
// }
// }
// Ok(VisitResult::Control(_flow)) => todo!(),
// Err(_) => todo!(),
// }
//
// Ok(())
// })
}
}