use effectful::{ blocking::BlockingSpin, bound::{Bool, Dynamic, IsSend, IsSync}, effective::{Canonical, Effective}, environment::Environment, forward_send_sync, DynBind, }; use mockall::mock; use treaty::{ any::{type_name, AnyTrait, OwnedStatic}, protocol::{ visitor::{visit_value, Value, VisitResult}, AsVisitor, DynVisitor, }, Flow, }; mock! { pub ValueVisitor where for<'a, 'ctx> type_name::Lowered<'a, 'ctx, T>: Sized { pub fn visit<'a, 'ctx>(&'a mut self, value: &type_name::Lowered<'a, 'ctx, T>) -> VisitResult<()>; } } forward_send_sync!({} {} {T: (type_name::Static + Send)} MockValueVisitor where { for<'a, 'ctx> type_name::Lowered<'a, 'ctx, T>: Sized }); // any_trait! { // impl['ctx, T][E] MockValueVisitor = [ // ValueProto // ] where // T: TypeName::MemberType, // for<'a, 'b> TypeName::T<'a, 'b, T, E>: Sized, // for<'a> Dynamic>: DynBind, // E: Environment, // } impl<'ctx, T: type_name::Static + Send, E: Environment> Value<'ctx, T, E> for MockValueVisitor where for<'a, 'b> type_name::Lowered<'a, 'b, T>: Sized, { fn visit<'r>( &'r mut self, value: type_name::Lowered<'r, 'ctx, T>, ) -> Canonical<'r, VisitResult>, E> where // type_name::Lowered<'value, 'ctx, T>: Sized, type_name::Lowered<'r, 'ctx, T>: DynBind, { todo!() } // fn visit<'a>( // &'a mut self, // value: TypeName::T<'a, 'ctx, T, E>, // ) -> Canonical<'a, VisitResult>>, E> // where // 'ctx: 'a, // { // E::value(match self.visit(&value) { // VisitResult::Skipped(_) => VisitResult::Skipped(Dynamic(value)), // VisitResult::Control(flow) => VisitResult::Control(flow), // }) // .cast() // } } pub trait ValueVisitorExt<'ctx> { fn visit_value_and_done<'a, T>(&'a mut self, value: T) where T: type_name::WithLt<'a, 'ctx> + DynBind, type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a; fn visit_value_and_skipped<'a, T>(&'a mut self, value: T) where T: type_name::WithLt<'a, 'ctx>, type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a; } impl<'ctx, U> ValueVisitorExt<'ctx> for U where U: AsVisitor<'ctx, BlockingSpin>, { #[track_caller] fn visit_value_and_done<'a, T>(&'a mut self, value: T) where T: type_name::WithLt<'a, 'ctx> + DynBind, type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a, { let result = visit_value::<_, BlockingSpin>(self.as_visitor(), value).wait(); assert_eq!(result, VisitResult::Control(Flow::Done)); } #[track_caller] fn visit_value_and_skipped<'a, T>(&'a mut self, value: T) where T: type_name::WithLt<'a, 'ctx>, type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a, { todo!() } // #[track_caller] // fn visit_value_and_done<'a, T>(&'a mut self, value: T) // where // T: TypeName::LowerType<'a, 'ctx, BlockingSpin>, // TypeName::HigherRanked<'a, 'ctx, T, BlockingSpin>: TypeName::MemberType, // 'ctx: 'a, // { // let result = visit_value::<_, BlockingSpin>(self.as_visitor(), value).into_value(); // // assert_eq!(result, VisitResult::Control(Flow::Done)); // } // // #[track_caller] // fn visit_value_and_skipped<'a, T>(&'a mut self, value: T) // where // T: TypeName::LowerType<'a, 'ctx, BlockingSpin>, // TypeName::HigherRanked<'a, 'ctx, T, BlockingSpin>: TypeName::MemberType, // 'ctx: 'a, // { // let result = visit_value::<_, BlockingSpin>(self.as_visitor(), value).into_value(); // // assert_eq!(result.unit_skipped(), VisitResult::Skipped(())); // } }