use mockall::{predicate::eq, Sequence};
use treaty::{
any::{OwnedStatic, TypeNameId},
effect::{BlockOn, Blocking, Effect, Future, Spin},
protocol::{
visitor::{TagConst, TagProto, ValueProto},
Visitor,
},
walkers::core::{
r#struct::{StructTypeInfo, StructWalker},
value::ValueWalker,
},
Builder, DefaultMode, Flow, Walker, TAG_STRUCT, TAG_TYPE_NAME,
};
use crate::common::{
builder::MockBuilder,
protocol::{tag::MockTagVisitor, visitor::MockValueVisitor},
};
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>(
index: usize,
value: &'ctx Self::T,
visitor: Visitor<'a, 'ctx>,
) -> Future<'a, 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::<
TagProto<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.into()
});
mock
})));
builder
.expect_traits_mut()
.once()
.with(eq(TypeNameId::of::<
TagProto<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::<
ValueProto<OwnedStatic<&'static str>, Blocking>,
>()))
.return_var(Some(Box::new({
let mut mock =
MockValueVisitor::<OwnedStatic<&'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.into()
});
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();
}