Diffstat (limited to 'src/walk/walkers/core/struct.rs')
| -rw-r--r-- | src/walk/walkers/core/struct.rs | 92 |
1 files changed, 77 insertions, 15 deletions
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs index 9dd5d68..88b597c 100644 --- a/src/walk/walkers/core/struct.rs +++ b/src/walk/walkers/core/struct.rs @@ -133,7 +133,8 @@ where .as_ctx( #[inline(always)] |(this, visitor)| { - RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()).into_erased() + RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()) + .into_erased() }, ) .map(|((this, _), _)| match this.error { @@ -626,23 +627,84 @@ where self.index = 0; E::ready((self, visitor)) - .as_ctx( - #[inline(always)] - |(this, visitor)| { + .as_ctx(|(this, visitor)| { + visit_request_hint::<E>(visitor.cast(), DynWalker(*this)) + .map(|result| match result { + VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => None, + VisitResult::Control(Flow::Done) => Some(Ok(())), + VisitResult::Control(Flow::Err) => Some(Err(())), + }) + .into_erased() + }) + .as_ctx(|((this, visitor), result)| { + if result.is_some() { + E::ready(None).into_erased() + } else { 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(()) + .map(|result| match result { + VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => None, + VisitResult::Control(Flow::Done) => Some(Ok(())), + VisitResult::Control(Flow::Err) => Some(Err(())), }) .into_erased() - }, - ) - .map(|(_, value)| value) + } + }) + .map(|((ctx, result), other)| match (result, other) { + (Some(result), None) => (ctx, Some(result)), + (None, Some(result)) => (ctx, Some(result)), + (Some(_), Some(_)) => unreachable!(), + (None, None) => (ctx, None), + }) + .as_ctx(|((this, visitor), result)| { + if result.is_some() { + E::ready(None).into_erased() + } else { + visit_value::<_, E>(visitor.cast(), BorrowedStatic(this.value)) + .map(|result| match result { + VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => None, + VisitResult::Control(Flow::Done) => Some(Ok(())), + VisitResult::Control(Flow::Err) => Some(Err(())), + }) + .into_erased() + } + }) + .map(|((ctx, result), other)| match (result, other) { + (Some(result), None) => (ctx, Some(result)), + (None, Some(result)) => (ctx, Some(result)), + (Some(_), Some(_)) => unreachable!(), + (None, None) => (ctx, None), + }) + .as_ctx(|((this, visitor), result)| { + if result.is_some() { + E::ready(None).into_erased() + } else { + visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>( + TagConst, + visitor.cast(), + ValueWalker::new(TypeId::of::<I::T>()), + ) + .map(|result| match result { + Err(err) => { + this.error = Some(StructWalkErrorKind::Tag(err)); + Some(Err(())) + } + Ok(VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_)) => None, + Ok(VisitResult::Control(Flow::Done)) => Some(Ok(())), + Ok(VisitResult::Control(Flow::Err)) => Some(Err(())), + }) + .into_erased() + } + }) + .map(|((ctx, result), other)| match (result, other) { + (Some(result), None) => (ctx, Some(result)), + (None, Some(result)) => (ctx, Some(result)), + (Some(_), Some(_)) => unreachable!(), + (None, None) => (ctx, None), + }) + .map(|(_, value)| match value { + None => Ok(()), + Some(value) => value, + }) .into_erased() // E::wrap(async move { |