Diffstat (limited to 'tests/builder_struct.rs')
| -rw-r--r-- | tests/builder_struct.rs | 263 |
1 files changed, 91 insertions, 172 deletions
diff --git a/tests/builder_struct.rs b/tests/builder_struct.rs index f77bd52..f9400c5 100644 --- a/tests/builder_struct.rs +++ b/tests/builder_struct.rs @@ -1,230 +1,149 @@ use macro_rules_attribute::derive; use treaty::{ any::{OwnedStatic, TempBorrowedStatic}, - builders::{self, core::r#struct::StructBuilder}, - effect::{blocking::Blocking, Effect, Effective, ErasedEffective}, + effect::blocking::Blocking, + protocol::visitor::{tags, visit_sequence, visit_tag, visit_value, TagConst, VisitResult}, + walkers::core::noop::NoopWalker, + Build, BuildExt as _, Builder, DefaultMode, Flow, +}; + +use crate::common::{ protocol::{ - visitor::{tags, visit_sequence, visit_tag, visit_value, TagConst, VisitResult}, - DynVisitor, + sequence::MockSequenceScope, + value::{MockValueVisitor, ValueVisitorExt as _}, }, - transform, - walkers::{ - self, - core::{noop::NoopWalker, r#struct::StructWalker}, - }, - Build, Builder, DefaultMode, Flow, Walk, Walker, + walker::MockWalker, }; -use crate::common::{protocol::sequence::MockSequenceScope, walker::MockWalker}; - mod common; -#[derive(Build!, Walk!, Debug, PartialEq)] +#[derive(Build!, Debug, PartialEq)] struct X { a: bool, b: bool, } #[test] -fn demo() { - let value = X { a: true, b: false }; +fn a_struct_builder_can_build_from_a_sequence_of_field_values() { + let mut scope; + { + // A tuple-like struct is just a sequence. + scope = MockSequenceScope::<Blocking>::new(); + + // First field. + scope.expect_next().once().returning(|visitor| { + // Visit a bool value. + visitor.visit_value_and_done(OwnedStatic(true)); + + // We have another field. + Flow::Continue + }); - let (other, _) = transform::<<X as Build<DefaultMode, _>>::Builder, _, Blocking>( - ((), ()), - <&X as Walk<DefaultMode, _>>::Walker::new(&value), - ) - .value(); + // Second field. + scope.expect_next().once().returning(|visitor| { + // Visit a bool value. + visitor.visit_value_and_done(OwnedStatic(false)); - assert_eq!(other.unwrap(), value); -} + // No more fields. + Flow::Done + }); + } -#[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 = <X as Build<DefaultMode, Blocking>>::Builder::from_seed(((), ())).value(); - let visitor = builder.as_visitor(); + // Make a builder for the struct. + let mut builder = X::new_builder(); // Visit the sequence of field values. + // The struct visitor should report as done. assert!(matches!( - visit_sequence(visitor, &mut scope).value(), + visit_sequence(builder.as_visitor(), &mut scope).value(), VisitResult::Control(Flow::Done) )); + // The builder should be able to build a instance of the struct. 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(); +fn a_struct_builder_can_build_from_a_sequence_of_keyed_values() { + let mut scope; + { + // A map is a sequence of keyed values. + 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; + { + walker = MockWalker::<(), ()>::new(); + + // We need to give the b field name in the key tag. + walker.expect_walk().once().returning(|visitor| { + visitor.visit_value_and_done(TempBorrowedStatic("b")); + + Ok(()) + }); + } - // We need to give the b field name in the key tag. - walker.expect_walk().once().returning(|visitor| { + // Tag the value with a key as the field name. assert_eq!( - visit_value::<_, Blocking>(visitor, TempBorrowedStatic("b")).value(), - VisitResult::Control(Flow::Done) + visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), + Ok(VisitResult::Control(Flow::Continue)), ); - Ok(()) - }); + // Visit the value as normal. + visitor.visit_value_and_done(OwnedStatic(true)); - // 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)), - ); + // There is another field. + Flow::Continue + }); - // Visit the value as normal. - assert_eq!( - visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), - VisitResult::Control(Flow::Done) - ); + // The other field. + scope.expect_next().once().returning(|mut visitor| { + let mut walker; + { + walker = MockWalker::<(), ()>::new(); - // There is another field. - Flow::Continue - }); + // Here we do field a. + walker.expect_walk().once().returning(|visitor| { + visitor.visit_value_and_done(TempBorrowedStatic("a")); - // The other field. - scope.expect_next().once().returning(|mut visitor| { - let mut walker = MockWalker::<(), ()>::new(); + Ok(()) + }); + } - // Here we do field a. - walker.expect_walk().once().returning(|visitor| { + // Tag the value with a key. assert_eq!( - visit_value::<_, Blocking>(visitor, TempBorrowedStatic("a")).value(), - VisitResult::Control(Flow::Done) + visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), + Ok(VisitResult::Control(Flow::Continue)), ); - 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. + visitor.visit_value_and_done(OwnedStatic(false)); - // 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 - }); + // 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); + // There are no more fields. + scope.expect_next().once().returning(|_visitor| Flow::Done); + } - let mut builder = <X as Build<DefaultMode, Blocking>>::Builder::from_seed(((), ())).value(); - let mut visitor = builder.as_visitor(); + let mut builder = X::new_builder(); // 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(), + visit_tag::<tags::Map, Blocking, _>(TagConst, builder.as_visitor(), NoopWalker::new()) + .value(), Ok(VisitResult::Control(Flow::Continue)) ); // Visit the sequence of fields. assert_eq!( - visit_sequence(visitor, &mut scope).value(), + visit_sequence(builder.as_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::{ - blocking::{BlockOn, Blocking, Spin}, - // r#async::Async, - Effective as _, - }, - transform, Build, DefaultMode, - }; - - #[derive(Walk!, Debug)] - pub struct X { - pub a: bool, - pub b: bool, - pub c: bool, - } - - #[derive(Build!, Debug, PartialEq)] - pub struct Y { - pub b: bool, - pub a: bool, - pub c: bool, - } - - #[no_mangle] - #[inline(never)] - pub fn ident(x: X) -> Y { - let other = - transform::<<Y as crate::Build<'_, DefaultMode, _>>::Builder, _, Blocking<Spin>>( - ((), (), ()), - Walk::<DefaultMode, _>::into_walker(&x), - ) - .value(); - - // let other = Spin::block_on(other.into_future()); - - other.0.unwrap() - } - - #[test] - fn demo() { - assert_eq!( - ident(X { - a: true, - b: false, - c: true - }), - Y { - a: true, - b: false, - c: true - } - ); - } -} |