Diffstat (limited to 'tests/builder_struct.rs')
-rw-r--r--tests/builder_struct.rs263
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
- }
- );
- }
-}