Diffstat (limited to 'src/walk/walkers/core/struct.rs')
-rw-r--r--src/walk/walkers/core/struct.rs333
1 files changed, 79 insertions, 254 deletions
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs
index 82e399d..393450f 100644
--- a/src/walk/walkers/core/struct.rs
+++ b/src/walk/walkers/core/struct.rs
@@ -3,15 +3,15 @@ use core::{any::TypeId, marker::PhantomData};
use crate::{
any::{AnyTrait, BorrowedStatic, BorrowedStaticHrt},
any_trait,
- effect::{all_ctx, merge_ctx, Effect, Effective, EffectiveExt, ErasedEffective},
+ effect::{Effect, EffectExt as _, Effective, EffectiveExt, ErasedEffective, ReadyExt as _},
hkt::Marker,
never::Never,
protocol::{
visitor::{
visit_recoverable, visit_request_hint, visit_sequence, visit_tag, visit_value,
- RecoverableKnown, RecoverableProto, RecoverableScope, SequenceKnown, SequenceProto,
- SequenceScope, TagConst, TagDyn, TagError, TagHint, TagKnown, TagProto, ValueKnown,
- ValueProto, VisitResult,
+ EffectiveVisitExt as _, RecoverableKnown, RecoverableProto, RecoverableScope,
+ SequenceKnown, SequenceProto, SequenceScope, TagConst, TagDyn, TagError, TagHint,
+ TagKnown, TagProto, ValueKnown, ValueProto, VisitResult,
},
walker::hint::{Hint, HintMeta, HintProto, MetaHint, MetaKnown},
DynVisitor, DynWalker,
@@ -104,6 +104,16 @@ where
_generics: Default::default(),
}
}
+
+ fn record_tag_error<U>(
+ &mut self,
+ result: Result<VisitResult<U>, TagError<Never>>,
+ ) -> VisitResult<U> {
+ result.unwrap_or_else(|err| {
+ self.error = Some(StructWalkErrorKind::Tag(err));
+ Flow::Err.into()
+ })
+ }
}
impl<'ctx, I, S, M, E> WalkerTypes for StructWalker<'ctx, I, S, M, E>
@@ -130,19 +140,15 @@ where
{
E::ready((self, visitor))
.as_ctx(
- all_ctx,
#[inline(always)]
- |(this, visitor), _| {
- RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast())
- .into_erased()
+ |(this, visitor)| {
+ RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()).cast()
},
- merge_ctx,
)
.map(|((this, _), _)| match this.error {
Some(err) => Err(StructWalkError { kind: err }),
None => Ok(()),
})
- .into_erased()
// E::ready(self).as_ctx_for::<'ctx, '_>(|this, _| {
// (RecoverableScope::<'ctx, E>::new_walk::<'_, 'b, '_>(this, visitor), PhantomData)
@@ -175,6 +181,7 @@ any_trait! {
] where
E: Effect,
I: StructTypeInfo<'ctx, M, S = StaticType>,
+ M: 'ctx,
I::T: 'static
}
@@ -205,7 +212,7 @@ where
&'a mut self,
_hint: &'a <RecoverableProto<E> as HintMeta>::Hint,
) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, RecoverableProto<E>>, ()>, E> {
- E::ready(Ok(RecoverableKnown)).into_erased()
+ E::ready(Ok(RecoverableKnown))
}
}
@@ -251,7 +258,6 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into_erased()
}
}
@@ -297,7 +303,6 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into_erased()
}
}
@@ -339,7 +344,6 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into_erased()
}
}
@@ -385,7 +389,6 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into_erased()
}
}
@@ -432,7 +435,6 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into_erased()
}
}
@@ -479,7 +481,7 @@ where
'ctx,
TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>,
>::hint(self, visitor, TagHint { kind: TagConst }),
- _ => E::ready(Flow::Continue).into_erased(),
+ _ => E::ready(Flow::Continue),
}
}
@@ -496,7 +498,6 @@ where
kind_available: Some(false),
}),
})
- .into_erased()
}
}
@@ -528,7 +529,7 @@ where
&'a mut self,
_hint: &'a (),
) -> ErasedEffective<'a, Result<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>, ()>, E> {
- E::ready(Ok(ValueKnown { preview: None })).into_erased()
+ E::ready(Ok(ValueKnown { preview: None }))
}
}
@@ -560,11 +561,10 @@ where
E::ready(Ok(SequenceKnown {
len: (len, Some(len)),
}))
- .into_erased()
}
}
-impl<'ctx, I, S, M, E> SequenceScope<'ctx, E> for StructWalker<'ctx, I, S, M, E>
+impl<'ctx, I, S, M: 'ctx, E> SequenceScope<'ctx, E> for StructWalker<'ctx, I, S, M, E>
where
E: Effect,
I: StructTypeInfo<'ctx, M, S = S>,
@@ -573,28 +573,29 @@ where
fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E> {
let len = I::FIELDS.len();
- E::ready((len, Some(len))).into_erased()
+ E::ready((len, Some(len)))
}
#[inline(always)]
- fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ErasedEffective<'a, Flow, E> {
+ fn next<'a: 'c, 'b: 'c, 'c>(
+ &'a mut self,
+ visitor: DynVisitor<'b, 'ctx>,
+ ) -> ErasedEffective<'c, Flow, E> {
if self.index >= I::FIELDS.len() {
- return E::ready(Flow::Done).into_erased();
+ return Flow::Done.ready();
}
let index = self.index;
self.index += 1;
- 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_erased()
+ 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
+ }
+ })
// E::map(
// I::walk_field::<E>(index, self.value, visitor),
@@ -610,7 +611,7 @@ where
}
}
-impl<'ctx, I, M, E> RecoverableScope<'ctx, E> for StructWalker<'ctx, I, StaticType, M, E>
+impl<'ctx, I, M: 'ctx, E> RecoverableScope<'ctx, E> for StructWalker<'ctx, I, StaticType, M, E>
where
E: Effect,
I: StructTypeInfo<'ctx, M, S = StaticType>,
@@ -619,7 +620,7 @@ where
#[inline(always)]
fn new_walk<'a: 'c, 'b: 'c, 'c>(
&'a mut self,
- mut visitor: DynVisitor<'b, 'ctx>,
+ visitor: DynVisitor<'b, 'ctx>,
) -> ErasedEffective<'c, Status, E> {
// Reset the errors to default state.
self.error = None;
@@ -627,225 +628,49 @@ where
// Reset the field index to the default.
self.index = 0;
- E::ready((self, visitor))
- .as_ctx(
- all_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()
- },
- merge_ctx,
+ E::as_ctx((self, visitor), |(this, visitor)| {
+ visit_request_hint::<E>(visitor.cast(), DynWalker(*this))
+ .map(VisitResult::unit_skipped)
+ .cast()
+ })
+ .if_not_finished(|(this, visitor)| {
+ visit_value::<_, E>(visitor.cast(), BorrowedStatic(this.value))
+ .map(VisitResult::unit_skipped)
+ .cast()
+ })
+ .if_not_finished(|(this, visitor)| {
+ visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>(
+ TagConst,
+ visitor.cast(),
+ ValueWalker::new(TypeId::of::<I::T>()),
)
- .as_ctx(
- all_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(_) => {
- None
- }
- VisitResult::Control(Flow::Done) => Some(Ok(())),
- VisitResult::Control(Flow::Err) => Some(Err(())),
- })
- .into_erased()
- }
- },
- merge_ctx,
+ .map(|result| this.record_tag_error(result).unit_skipped())
+ .cast()
+ })
+ .if_not_finished(|(this, visitor)| {
+ visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(
+ TagConst,
+ visitor.cast(),
+ NoopWalker::new(),
)
- .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_or_else(|(this, visitor)| {
- // .as_ctx(all_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_or_else(|(this, visitor)| {
- 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()
- })
- // .as_ctx(all_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 {
- // // // We should check if the visitor wants something specific.
- // // match visit_request_hint::<E>(visitor.cast(), DynWalker(self)).await {
- // // VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue) => {}
- // // VisitResult::Control(Flow::Done) => return Ok(()),
- // // VisitResult::Control(Flow::Err) => return Err(()),
- // // }
- // //
- // // // Attempt to visit the value directly.
- // // match visit_value::<_, E>(visitor.cast(), BorrowedStatic(self.value)).await {
- // // VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue) => {}
- // // VisitResult::Control(Flow::Done) => return Ok(()),
- // // VisitResult::Control(Flow::Err) => return Err(()),
- // // }
- // //
- // // // Follow the standard set of protocols for a struct.
- // // // - Tagged: type ID
- // // // - Tagged: struct
- // // // - Tagged: struct name
- // // // - Tagged: struct field names
- // // // - Sequence: the fields
- // //
- // // match visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>(
- // // TagConst,
- // // visitor.cast(),
- // // ValueWalker::new(TypeId::of::<I::T>()),
- // // )
- // // .await
- // // {
- // // Err(err) => {
- // // self.error = Some(StructWalkErrorKind::Tag(err));
- // // return Err(());
- // // }
- // // Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
- // // Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
- // // Ok(VisitResult::Control(Flow::Err)) => return Err(()),
- // // }
- // //
- // // match visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(
- // // TagConst,
- // // visitor.cast(),
- // // NoopWalker::new(),
- // // )
- // // .await
- // // {
- // // Ok(VisitResult::Skipped(_)) => {
- // // match visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(
- // // TagConst,
- // // visitor.cast(),
- // // NoopWalker::new(),
- // // )
- // // .await
- // // {
- // // Err(err) => {
- // // self.error = Some(StructWalkErrorKind::Tag(err));
- // // return Err(());
- // // }
- // // Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
- // // Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
- // // Ok(VisitResult::Control(Flow::Err)) => return Err(()),
- // // }
- // // }
- // // Err(err) => {
- // // self.error = Some(StructWalkErrorKind::Tag(err));
- // // return Err(());
- // // }
- // // Ok(VisitResult::Control(Flow::Continue)) => {}
- // // Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
- // // Ok(VisitResult::Control(Flow::Err)) => return Err(()),
- // // }
- // //
- // // match visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(
- // // TagConst,
- // // visitor.cast(),
- // // ValueWalker::new(I::NAME),
- // // )
- // // .await
- // // {
- // // Err(err) => {
- // // self.error = Some(StructWalkErrorKind::Tag(err));
- // // return Err(());
- // // }
- // // Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
- // // Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
- // // Ok(VisitResult::Control(Flow::Err)) => return Err(()),
- // // }
- // //
- // // match visit_tag::<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E, _>(
- // // TagConst,
- // // visitor.cast(),
- // // StaticSliceWalker::<_, ValueWalker<&'static str>>::new(I::FIELDS),
- // // )
- // // .await
- // // {
- // // Err(err) => {
- // // self.error = Some(StructWalkErrorKind::FieldTag(err));
- // // return Err(());
- // // }
- // // Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
- // // Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
- // // Ok(VisitResult::Control(Flow::Err)) => return Err(()),
- // // }
- //
- // match visit_sequence::<E>(visitor, self).await {
- // VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => {}
- // VisitResult::Control(Flow::Done) => return Ok(()),
- // VisitResult::Control(Flow::Err) => return Err(()),
- // }
- //
- // Ok(())
- // })
+ .map(|result| this.record_tag_error(result).unit_skipped())
+ .cast()
+ })
+ .if_skipped(|(this, visitor)| {
+ visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(
+ TagConst,
+ visitor.cast(),
+ NoopWalker::new(),
+ )
+ .map(|result| this.record_tag_error(result).unit_skipped())
+ .cast()
+ })
+ .if_not_finished(|(this, visitor)| {
+ visit_sequence::<E>(visitor.cast(), *this)
+ .map(VisitResult::unit_skipped)
+ .cast()
+ })
+ .remove_ctx()
+ .map(VisitResult::to_status)
}
}