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