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