Diffstat (limited to 'tests/builder_struct.rs')
| -rw-r--r-- | tests/builder_struct.rs | 341 |
1 files changed, 175 insertions, 166 deletions
diff --git a/tests/builder_struct.rs b/tests/builder_struct.rs index c0cb843..c45a78f 100644 --- a/tests/builder_struct.rs +++ b/tests/builder_struct.rs @@ -1,7 +1,7 @@ use treaty::{ any::{OwnedStatic, TempBorrowedStatic}, builders::{self, core::r#struct::StructBuilder}, - effect::{ErasedEffective, Effect, Effective}, + effect::{blocking::Blocking, Effect, Effective, ErasedEffective}, protocol::{ visitor::{tags, visit_sequence, visit_tag, visit_value, TagConst, VisitResult}, DynVisitor, @@ -17,9 +17,9 @@ use treaty::{ Build, Builder, DefaultMode, Flow, Walk, Walker, }; -// use crate::common::{protocol::sequence::MockSequenceScope, walker::MockWalker}; -// -// mod common; +use crate::common::{protocol::sequence::MockSequenceScope, walker::MockWalker}; + +mod common; #[derive(Debug, PartialEq)] struct X { @@ -108,14 +108,16 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo type Error = (); #[inline(always)] - fn from_builders<'a>(builders: Self::Builders) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E> { - todo!() - // E::wrap(async { - // Ok(X { - // a: builders.a.build().await.unwrap(), - // b: builders.b.build().await.unwrap(), - // }) - // }) + fn from_builders<'a>( + builders: Self::Builders, + ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E> { + E::from_future(async { + Ok(X { + a: builders.a.build().into_future().await.unwrap(), + b: builders.b.build().into_future().await.unwrap(), + }) + }) + .into_erased() } #[inline(always)] @@ -133,167 +135,174 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo #[inline(always)] fn new_builders<'a>(_seed: Self::Seed) -> ErasedEffective<'a, Self::Builders, E> { - todo!() - // E::wrap(async { - // Fields { - // a: Builder::<E>::from_seed(()).await, - // b: Builder::<E>::from_seed(()).await, - // } - // }) + E::from_future(async { + Fields { + a: Builder::<E>::from_seed(()).into_future().await, + b: Builder::<E>::from_seed(()).into_future().await, + } + }) + .into_erased() } } -// #[test] -// #[ignore] -// fn demo() { -// let value = X { a: true, b: false }; -// -// let (other, _) = transform::<StructBuilder<Info, DefaultMode, _>, _, Blocking>( -// (), -// StructWalker::<Info, _, DefaultMode, _>::new(&value), -// ) -// .value(); -// -// assert_eq!(other.unwrap(), value); -// } -// -// #[test] -// fn from_basic_tuple_like() { -// // A tuple like is just a sequence. -// let mut scope = MockSequenceScope::<Blocking>::new(); -// -// // First field. -// scope.expect_next().once().returning(|visitor| { -// // Visit a bool value. -// // -// // The bool visitor should report that it is done. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // We have another field. -// Flow::Continue -// }); -// -// // Second field. -// scope.expect_next().once().returning(|visitor| { -// // Visit a bool value. -// // -// // The bool visitor should report that it is done. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // No more fields. -// Flow::Done -// }); -// -// let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); -// let visitor = builder.as_visitor(); -// -// // Visit the sequence of field values. -// assert!(matches!( -// visit_sequence(visitor, &mut scope).value(), -// VisitResult::Control(Flow::Done) -// )); -// -// assert_eq!(builder.build().value().unwrap(), X { a: true, b: false }); -// } -// -// #[test] -// fn from_basic_map_like() { -// // A map is built from a sequence. -// let mut scope = MockSequenceScope::<Blocking>::new(); -// -// // Here we do the b field first to show a map-like doesn't care about order. -// scope.expect_next().once().returning(|mut visitor| { -// let mut walker = MockWalker::<(), ()>::new(); -// -// // We need to give the b field name in the key tag. -// walker.expect_walk().once().returning(|visitor| { -// assert_eq!( -// visit_value::<_, Blocking>(visitor, TempBorrowedStatic("b")).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// Ok(()) -// }); -// -// // Tag the value with a key as the field name. -// assert_eq!( -// visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), -// Ok(VisitResult::Control(Flow::Continue)), -// ); -// -// // Visit the value as normal. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // There is another field. -// Flow::Continue -// }); -// -// // The other field. -// scope.expect_next().once().returning(|mut visitor| { -// let mut walker = MockWalker::<(), ()>::new(); -// -// // Here we do field a. -// walker.expect_walk().once().returning(|visitor| { -// assert_eq!( -// visit_value::<_, Blocking>(visitor, TempBorrowedStatic("a")).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// Ok(()) -// }); -// -// // Tag the value with a key. -// assert_eq!( -// visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), -// Ok(VisitResult::Control(Flow::Continue)), -// ); -// -// // The field value. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // The sequence protocol allows for us to wait to decide if there is another item. -// Flow::Continue -// }); -// -// // There are no more fields. -// scope.expect_next().once().returning(|_visitor| Flow::Done); -// -// let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); -// let mut visitor = builder.as_visitor(); -// -// // We need to provide the map tag to the struct before getting into the sequence. -// // This tag notifies the struct builder to expect the sequence as a map. -// assert_eq!( -// visit_tag::<tags::Map, Blocking, _>(TagConst, visitor.cast(), NoopWalker::new()).value(), -// Ok(VisitResult::Control(Flow::Continue)) -// ); -// -// // Visit the sequence of fields. -// assert_eq!( -// visit_sequence(visitor, &mut scope).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // The struct is built as the mock walker above makes it. -// assert_eq!(builder.build().value().unwrap(), X { a: false, b: true }); -// } +#[test] +#[ignore] +fn demo() { + let value = X { a: true, b: false }; + + let (other, _) = transform::<StructBuilder<Info, DefaultMode, _>, _, Blocking>( + (), + StructWalker::<Info, _, DefaultMode, _>::new(&value), + ) + .value(); + + assert_eq!(other.unwrap(), value); +} + +#[test] +fn from_basic_tuple_like() { + // A tuple like is just a sequence. + let mut scope = MockSequenceScope::<Blocking>::new(); + + // First field. + scope.expect_next().once().returning(|visitor| { + // Visit a bool value. + // + // The bool visitor should report that it is done. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), + VisitResult::Control(Flow::Done) + ); + + // We have another field. + Flow::Continue + }); + + // Second field. + scope.expect_next().once().returning(|visitor| { + // Visit a bool value. + // + // The bool visitor should report that it is done. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), + VisitResult::Control(Flow::Done) + ); + + // No more fields. + Flow::Done + }); + + let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); + let visitor = builder.as_visitor(); + + // Visit the sequence of field values. + assert!(matches!( + visit_sequence(visitor, &mut scope).value(), + VisitResult::Control(Flow::Done) + )); + + assert_eq!(builder.build().value().unwrap(), X { a: true, b: false }); +} + +#[test] +fn from_basic_map_like() { + // A map is built from a sequence. + let mut scope = MockSequenceScope::<Blocking>::new(); + + // Here we do the b field first to show a map-like doesn't care about order. + scope.expect_next().once().returning(|mut visitor| { + let mut walker = MockWalker::<(), ()>::new(); + + // We need to give the b field name in the key tag. + walker.expect_walk().once().returning(|visitor| { + assert_eq!( + visit_value::<_, Blocking>(visitor, TempBorrowedStatic("b")).value(), + VisitResult::Control(Flow::Done) + ); + + Ok(()) + }); + + // Tag the value with a key as the field name. + assert_eq!( + visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), + Ok(VisitResult::Control(Flow::Continue)), + ); + + // Visit the value as normal. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), + VisitResult::Control(Flow::Done) + ); + + // There is another field. + Flow::Continue + }); + + // The other field. + scope.expect_next().once().returning(|mut visitor| { + let mut walker = MockWalker::<(), ()>::new(); + + // Here we do field a. + walker.expect_walk().once().returning(|visitor| { + assert_eq!( + visit_value::<_, Blocking>(visitor, TempBorrowedStatic("a")).value(), + VisitResult::Control(Flow::Done) + ); + + Ok(()) + }); + + // Tag the value with a key. + assert_eq!( + visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), + Ok(VisitResult::Control(Flow::Continue)), + ); + + // The field value. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), + VisitResult::Control(Flow::Done) + ); + + // The sequence protocol allows for us to wait to decide if there is another item. + Flow::Continue + }); + + // There are no more fields. + scope.expect_next().once().returning(|_visitor| Flow::Done); + + let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); + let mut visitor = builder.as_visitor(); + + // We need to provide the map tag to the struct before getting into the sequence. + // This tag notifies the struct builder to expect the sequence as a map. + assert_eq!( + visit_tag::<tags::Map, Blocking, _>(TagConst, visitor.cast(), NoopWalker::new()).value(), + Ok(VisitResult::Control(Flow::Continue)) + ); + + // Visit the sequence of fields. + assert_eq!( + visit_sequence(visitor, &mut scope).value(), + VisitResult::Control(Flow::Done) + ); + + // The struct is built as the mock walker above makes it. + assert_eq!(builder.build().value().unwrap(), X { a: false, b: true }); +} pub mod demo { use crate::Walk; use macro_rules_attribute::derive; - use treaty::{effect::{r#async::Async, blocking::{BlockOn, Blocking, Spin}, Effective as _}, transform, Build, DefaultMode}; + use treaty::{ + effect::{ + blocking::{BlockOn, Blocking, Spin}, + r#async::Async, + Effective as _, + }, + transform, Build, DefaultMode, + }; #[derive(Walk!, Debug)] pub struct X { |