Diffstat (limited to 'src/walk/walkers/core/struct.rs')
-rw-r--r--src/walk/walkers/core/struct.rs73
1 files changed, 63 insertions, 10 deletions
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs
index 46ac3a6..d6c8c4b 100644
--- a/src/walk/walkers/core/struct.rs
+++ b/src/walk/walkers/core/struct.rs
@@ -1,9 +1,9 @@
-use core::any::TypeId;
+use core::{any::TypeId, marker::PhantomData};
use crate::{
any::{AnyTrait, BorrowedStatic, BorrowedStaticHrt},
any_trait,
- effect::{Effect, ObjSafe},
+ effect::{Adapters, Effect, ObjSafe},
hkt::Marker,
never::Never,
protocol::{
@@ -122,14 +122,33 @@ where
Self: AnyTrait<'ctx> + RecoverableScope<'ctx, E>,
{
#[inline(always)]
- fn walk<'a>(
+ fn walk<'b: 'c, 'c>(
mut self,
- mut visitor: DynVisitor<'a, 'ctx>,
- ) -> ObjSafe<'a, Result<Self::Output, Self::Error>, E>
+ mut visitor: DynVisitor<'b, 'ctx>,
+ ) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E>
where
- Self: 'a,
+ Self: 'c,
{
- todo!()
+ E::ready((self, visitor))
+ .as_ctx_for(
+ #[inline(always)]
+ |(this, visitor), _| {
+ (
+ RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()),
+ PhantomData,
+ )
+ },
+ )
+ .map(|((this, _), _)| match this.error {
+ Some(err) => Err(StructWalkError { kind: err }),
+ None => Ok(()),
+ })
+ .into()
+
+ // E::ready(self).as_ctx_for::<'ctx, '_>(|this, _| {
+ // (RecoverableScope::<'ctx, E>::new_walk::<'_, 'b, '_>(this, visitor), PhantomData)
+ // });
+
// E::wrap(async move {
// // Use the recoverable walk to not duplicate the code.
// let _ = RecoverableScope::<'ctx, E>::new_walk(&mut self, visitor.cast()).await;
@@ -560,7 +579,17 @@ where
let index = self.index;
self.index += 1;
- todo!()
+ I::walk_field::<E>(index, self.value, visitor)
+ .map(|result| match result {
+ Ok(flow) => flow,
+ Err(err) => {
+ // Record the error and signal a break.
+ self.error = Some(StructWalkErrorKind::Field(err));
+ Flow::Err
+ }
+ })
+ .into()
+
// E::map(
// I::walk_field::<E>(index, self.value, visitor),
// |result| match result {
@@ -582,14 +611,38 @@ where
I::T: 'static,
{
#[inline(always)]
- fn new_walk<'a>(&'a mut self, mut visitor: DynVisitor<'a, 'ctx>) -> ObjSafe<'a, Status, E> {
+ fn new_walk<'a: 'c, 'b: 'c, 'c>(
+ &'a mut self,
+ mut visitor: DynVisitor<'b, 'ctx>,
+ ) -> ObjSafe<'c, Status, E> {
// Reset the errors to default state.
self.error = None;
// Reset the field index to the default.
self.index = 0;
- todo!()
+ E::with(
+ (self, visitor),
+ #[inline(always)]
+ |(this, visitor), _| {
+ (
+ visit_sequence::<E>(visitor.cast(), *this)
+ .map(|result| {
+ match result {
+ VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => {}
+ VisitResult::Control(Flow::Done) => return Ok(()),
+ VisitResult::Control(Flow::Err) => return Err(()),
+ }
+
+ Ok(())
+ })
+ .into(),
+ PhantomData,
+ )
+ },
+ )
+ .into()
+
// E::wrap(async move {
// // // We should check if the visitor wants something specific.
// // match visit_request_hint::<E>(visitor.cast(), DynWalker(self)).await {