Diffstat (limited to 'src/walk/walkers/core/struct.rs')
| -rw-r--r-- | src/walk/walkers/core/struct.rs | 242 |
1 files changed, 42 insertions, 200 deletions
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs index e78094e..406e703 100644 --- a/src/walk/walkers/core/struct.rs +++ b/src/walk/walkers/core/struct.rs @@ -1,24 +1,19 @@ -use core::{any::TypeId, marker::PhantomData}; +use core::any::TypeId; use crate::{ - any::static_wrapper::{BorrowedStatic, DynBorrowedStatic}, - any_trait, - effect::{Effect, Future}, - never::Never, - protocol::{ + any::static_wrapper::{BorrowedStatic, DynBorrowedStatic}, any_trait, effect::{Effect, Future}, hkt::Marker, never::Never, protocol::{ visitor::{ recoverable::{visit_recoverable, DynRecoverable, RecoverableScope}, request_hint::visit_request_hint, sequence::{visit_sequence, DynSequence, SequenceKnown, SequenceScope}, tag::{visit_tag, DynTag, TagConst, TagDyn, TagError, TagHint, TagKnown}, - value::{visit_value, DynValue}, + value::{visit_value, DynValue, ValueKnown}, Status, }, walker::hint::{DynHint, HintMeta}, walker::hint::{Hint, Known}, Visitor, - }, - Flow, WalkerTypes, TAG_FIELD_NAMES, TAG_MAP, TAG_STRUCT, TAG_TYPE_ID, TAG_TYPE_NAME, + }, Flow, WalkerTypes, TAG_FIELD_NAMES, TAG_MAP, TAG_STRUCT, TAG_TYPE_ID, TAG_TYPE_NAME }; use super::{noop::NoopWalker, tag::StaticSliceWalker, value::ValueWalker}; @@ -38,7 +33,7 @@ pub struct StructWalker<'ctx, T, I: StructTypeInfo<'ctx, M>, M, E> { /// The visitor tracks it's own errors. error: Option<StructWalkErrorKind<I::FieldError>>, - _marker: PhantomData<fn() -> (I, M, E)>, + _generics: Marker<(I, M, E)>, } /// Type info about a struct needed by [`StructWalker`]. @@ -56,14 +51,15 @@ pub trait StructTypeInfo<'ctx, M>: 'static { type T: Send; /// Walk the given field. - fn walk_field<'a, E: Effect<'ctx>>( + fn walk_field<'a, E: Effect>( index: usize, value: &'ctx Self::T, visitor: Visitor<'a, 'ctx>, - ) -> Future<'a, 'ctx, Result<Flow, Self::FieldError>, E>; + ) -> Future<'a, Result<Flow, Self::FieldError>, E>; } #[derive(Debug)] +#[allow(unused)] enum StructWalkErrorKind<T> { /// Error with visiting a tag for the struct. /// @@ -81,6 +77,7 @@ enum StructWalkErrorKind<T> { /// Error from walking a struct. #[derive(Debug)] +#[allow(unused)] pub struct StructWalkError<T> { kind: StructWalkErrorKind<T>, } @@ -95,7 +92,7 @@ where value, index: 0, error: None, - _marker: PhantomData, + _generics: Default::default(), } } } @@ -110,14 +107,14 @@ where impl<'ctx, T, I, E, M> crate::Walker<'ctx, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M, T = T>, T: Sync + 'static, { fn walk<'a>( mut self, visitor: Visitor<'a, 'ctx>, - ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E> + ) -> Future<'a, Result<Self::Output, Self::Error>, E> where Self: 'a, { @@ -146,14 +143,14 @@ any_trait! { DynHint<'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E>, E>, DynHint<'ctx, DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, E>, ] where - E: Effect<'ctx>, + E: Effect, T: Sync + 'static, I: StructTypeInfo<'ctx, M, T = T> } impl<'ctx, T, I, M, E> Hint<'ctx, DynRecoverable<'ctx, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M, T = T>, T: Sync + 'static, { @@ -161,7 +158,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, _hint: <DynRecoverable<'ctx, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { E::map( visit_recoverable::<E>(visitor, self), |status| match status { @@ -174,7 +171,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <DynRecoverable<'ctx, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynRecoverable<'ctx, E>>, ()>, E> { + ) -> Future<'a, Result<Known<'a, 'ctx, DynRecoverable<'ctx, E>>, ()>, E> { E::ready(Ok(())) } } @@ -182,7 +179,7 @@ where impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M>, T: Sync + 'static, { @@ -190,7 +187,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, _hint: <DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { E::map( visit_tag::<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E, _>( TagConst, @@ -213,9 +210,7 @@ where _hint: &'a <DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E> as HintMeta< 'ctx, >>::Hint, - ) -> Future< - 'a, - 'ctx, + ) -> Future<'a, Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, ()>, E, > { @@ -228,7 +223,7 @@ where impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M>, T: Sync + 'static, { @@ -236,7 +231,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, _hint: <DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { E::map( visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>( TagConst, @@ -259,7 +254,6 @@ where _hint: &'a <DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta<'ctx>>::Hint, ) -> Future< 'a, - 'ctx, Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, ()>, E, > { @@ -272,7 +266,7 @@ where impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M>, T: Sync + 'static, { @@ -280,7 +274,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, _hint: <DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { E::map( visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()), |status| match status { @@ -299,7 +293,6 @@ where _hint: &'a <DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta<'ctx>>::Hint, ) -> Future< 'a, - 'ctx, Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E>>, ()>, E, > { @@ -312,7 +305,7 @@ where impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M>, T: Sync + 'static, { @@ -320,7 +313,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, _hint: <DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { E::map( visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>( TagConst, @@ -343,7 +336,6 @@ where _hint: &'a <DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta<'ctx>>::Hint, ) -> Future< 'a, - 'ctx, Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E>>, ()>, E, > { @@ -356,7 +348,7 @@ where impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M>, T: Sync + 'static, { @@ -364,7 +356,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, _hint: <DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { E::map( visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>( TagConst, @@ -387,7 +379,6 @@ where _hint: &'a <DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta<'ctx>>::Hint, ) -> Future< 'a, - 'ctx, Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, ()>, E, > { @@ -399,7 +390,7 @@ where impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagDyn, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M>, T: Sync + 'static, { @@ -407,7 +398,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, hint: <DynTag<'ctx, TagDyn, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { match hint.kind.0 { crate::TAG_TYPE_ID => Hint::< 'ctx, @@ -445,7 +436,7 @@ where fn known<'a>( &'a mut self, hint: &'a <DynTag<'ctx, TagDyn, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynTag<'ctx, TagDyn, E>>, ()>, E> { + ) -> Future<'a, Result<Known<'a, 'ctx, DynTag<'ctx, TagDyn, E>>, ()>, E> { E::ready(match hint.kind { TagDyn(crate::TAG_TYPE_ID) | TagDyn(crate::TAG_STRUCT) => Ok(TagKnown { kind_available: Some(true), @@ -460,11 +451,11 @@ where impl<'ctx, T, I, M, E> Hint<'ctx, DynValue<'ctx, DynBorrowedStatic<'ctx, T>, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M>, T: Sync + 'static, { - fn hint<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>, _hint: ()) -> Future<'a, 'ctx, Flow, E> { + fn hint<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>, _hint: ()) -> Future<'a, Flow, E> { E::map( visit_value::<_, E>(visitor, BorrowedStatic(self.value)), |status| match status { @@ -474,14 +465,14 @@ where ) } - fn known<'a>(&'a mut self, _hint: &'a ()) -> Future<'a, 'ctx, Result<(), ()>, E> { - E::ready(Ok(())) + fn known<'a>(&'a mut self, _hint: &'a ()) -> Future<'a, Result<ValueKnown, ()>, E> { + E::ready(Ok(ValueKnown)) } } impl<'ctx, T, I, M, E> Hint<'ctx, DynSequence<'ctx, E>, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M, T = T>, T: Sync, { @@ -489,7 +480,7 @@ where &'a mut self, visitor: Visitor<'a, 'ctx>, _hint: <DynSequence<'ctx, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Flow, E> { + ) -> Future<'a, Flow, E> { E::map(visit_sequence::<E>(visitor, self), |status| match status { Status::Skipped(_) => Flow::Continue, Status::Flow(flow) => flow, @@ -499,7 +490,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <DynSequence<'ctx, E> as HintMeta<'ctx>>::Hint, - ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynSequence<'ctx, E>>, ()>, E> { + ) -> Future<'a, Result<Known<'a, 'ctx, DynSequence<'ctx, E>>, ()>, E> { let len = I::FIELDS.len(); E::ready(Ok(SequenceKnown { @@ -510,16 +501,16 @@ where impl<'ctx, T, I, M, E> SequenceScope<'ctx, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M, T = T>, { - fn size_hint<'a>(&'a mut self) -> Future<'a, 'ctx, (usize, Option<usize>), E> { + fn size_hint(&mut self) -> Future<'_, (usize, Option<usize>), E> { let len = I::FIELDS.len(); E::ready((len, Some(len))) } - fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E> { + fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E> { if self.index >= I::FIELDS.len() { return E::ready(Flow::Done); } @@ -543,11 +534,11 @@ where impl<'ctx, T, I, M, E> RecoverableScope<'ctx, E> for StructWalker<'ctx, T, I, M, E> where - E: Effect<'ctx>, + E: Effect, I: StructTypeInfo<'ctx, M, T = T>, T: Sync + 'static, { - fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E> { + fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E> { // Reset the errors to default state. self.error = None; @@ -659,152 +650,3 @@ where }) } } - -#[cfg(test)] -mod test { - use mockall::{predicate::eq, Sequence}; - - use crate::{ - any::{ - static_wrapper::{DynOwnedStatic, OwnedStatic}, - TypeNameId, - }, - effect::{BlockOn as _, Blocking, Spin}, - mock::{ - builder::MockBuilder, - protocol::{tag::MockTagVisitor, value::MockValueVisitor}, - }, - symbol::Symbol, - Builder, DefaultMode, Walker, - }; - - use super::*; - - struct Demo { - a: bool, - b: bool, - } - - impl<'ctx, M> StructTypeInfo<'ctx, M> for Demo { - const NAME: &'static str = "Demo"; - - const FIELDS: &'static [&'static str] = &["a", "b"]; - - type FieldError = (); - - type T = Demo; - - fn walk_field<'a, E: Effect<'ctx>>( - index: usize, - value: &'ctx Self::T, - visitor: Visitor<'a, 'ctx>, - ) -> Future<'a, 'ctx, Result<Flow, Self::FieldError>, E> { - E::wrap(async move { - match index { - 0 => { - let walker = ValueWalker::<bool>::new(value.a); - Walker::<E>::walk(walker, visitor).await.unwrap(); - Ok(Flow::Continue) - } - 1 => { - let walker = ValueWalker::<bool>::new(value.b); - Walker::<E>::walk(walker, visitor).await.unwrap(); - Ok(Flow::Continue) - } - _ => Ok(Flow::Done), - } - }) - } - } - - #[test] - fn demo2() { - let mut builder = MockBuilder::<(), (), ()>::new(); - - let mut seq = Sequence::new(); - - builder - .expect_traits_mut() - .times(4) - .in_sequence(&mut seq) - .return_var(None); - - builder - .expect_traits_mut() - .once() - .with(eq(TypeNameId::of::< - DynTag<'static, TagConst<{ TAG_STRUCT.to_int() }>, Blocking>, - >())) - .in_sequence(&mut seq) - .return_var(Some(Box::new({ - let mut mock = MockTagVisitor::<TagConst<{ TAG_STRUCT.to_int() }>, Blocking>::new(); - - mock.expect_visit().once().returning(|_, walker| { - let mut builder = MockBuilder::<(), (), ()>::new(); - assert_eq!( - Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))), - Flow::Done - ); - - Flow::Continue - }); - - mock - }))); - - builder - .expect_traits_mut() - .once() - .with(eq(TypeNameId::of::< - DynTag<'static, TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>, - >())) - .in_sequence(&mut seq) - .return_var(Some(Box::new({ - let mut mock = - MockTagVisitor::<TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>::new(); - - mock.expect_visit().return_once(|_, walker| { - let mut builder = MockBuilder::<(), (), ()>::new(); - - builder - .expect_traits_mut() - .once() - .with(eq(TypeNameId::of::< - DynValue<'static, DynOwnedStatic<&'static str>, Blocking>, - >())) - .return_var(Some(Box::new({ - let mut mock = - MockValueVisitor::<DynOwnedStatic<&'static str>, Blocking>::new(); - - mock.expect_visit() - .once() - .with(eq(OwnedStatic("Demo"))) - .return_const(Flow::Done); - - mock - }))); - - assert_eq!( - Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))), - Flow::Done - ); - - Flow::Continue - }); - - mock - }))); - - builder - .expect_traits_mut() - .times(3) - .in_sequence(&mut seq) - .return_var(None); - - let value = Demo { a: true, b: false }; - - let walker = StructWalker::<Demo, Demo, DefaultMode, Blocking>::new(&value); - - Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))).unwrap(); - } -} |