use effectful::{ blocking::BlockingSpin, bound::{Bool, IsSend, IsSync}, effective::{Canonical, Effective}, environment::Environment, forward_send_sync, }; use mockall::mock; use treaty::{ any::AnyTrait, protocol::{ visitor::{visit_tag, ConstTagKind, Tag, TagConst, TagKind, VisitResult}, AsVisitor, DynVisitor, }, walk::DynWalkerObjSafe, Flow, Walker, }; mock! { pub TagVisitor, E: Environment> { pub fn visit<'r, 'ctx>(&'r mut self, kind: K, walker: DynWalkerObjSafe<'r, 'ctx, E>) -> VisitResult; } } forward_send_sync!({K: (TagKind + Send)} {} {E: (Environment + Send)} MockTagVisitor); // any_trait! { // impl['ctx, K][E] MockTagVisitor = [ // TagProto, // ] where // K: TagKind, // E: Environment, // } impl<'ctx, K: TagKind + Send, E: Environment + Send> Tag<'ctx, K, E> for MockTagVisitor { fn visit<'r>( &'r mut self, kind: K, walker: DynWalkerObjSafe<'r, 'ctx, E>, ) -> Canonical<'r, VisitResult, E> { E::value(self.visit(kind, walker)).cast() } } pub trait TagVisitorExt<'ctx> { fn visit_tag_and_done<'a, T: ConstTagKind, W: Walker<'ctx, BlockingSpin>>( &'a mut self, walker: W, ); } impl<'ctx, T> TagVisitorExt<'ctx> for T where T: AsVisitor<'ctx, BlockingSpin>, { fn visit_tag_and_done<'a, Tag: ConstTagKind, W: Walker<'ctx, BlockingSpin>>( &'a mut self, walker: W, ) { let result = visit_tag::(Tag::NEW, self.as_visitor(), walker).wait(); assert_eq!(result.unwrap(), VisitResult::Control(Flow::Done)); } }