Diffstat (limited to 'src/build.rs')
| -rw-r--r-- | src/build.rs | 103 |
1 files changed, 79 insertions, 24 deletions
diff --git a/src/build.rs b/src/build.rs index 0f70423..f116bcb 100644 --- a/src/build.rs +++ b/src/build.rs @@ -55,10 +55,19 @@ pub trait Builder<'ctx, E: Effect<'ctx>>: BuilderTypes + Sized + Send { #[cfg(test)] pub mod test { - use std::{collections::HashMap, sync::{Mutex, MutexGuard, PoisonError}}; + use std::{ + collections::HashMap, + sync::{Mutex, MutexGuard, PoisonError}, + }; use crate::{ - any::{static_wrapper::OwnedStatic, AnyTrait, Indirect, IndirectLtAny, LtTypeId, Mut, Ref, TypeNameable}, effect::{BlockOn, Blocking, Spin}, protocol::visitor::value::{DynValue, Value}, Flow + any::{ + static_wrapper::{DynOwnedStatic, OwnedStatic}, + AnyTrait, Boxed, Indirect, IndirectLtAny, LtTypeId, MaybeSized, Mut, Ref, TypeName, + }, + effect::{BlockOn, Blocking, Spin}, + protocol::visitor::value::{DynValue, Value}, + Flow, }; use super::*; @@ -87,21 +96,41 @@ pub mod test { pub type MockBuilder<Seed = (), Value = (), Error = ()> = mock::MockBuilder<Seed, Value, Error>; - trait MockIndirect: Send { + pub trait MockIndirect: Send { fn indirect(&self) -> IndirectLtAny<'_, 'static, Ref>; - fn indirect_mut(&mut self) -> IndirectLtAny<'_, 'static, Mut>; + fn indirect_mut<'a: 'b, 'b>(&'a mut self) -> IndirectLtAny<'b, 'static, Mut>; } - impl<T: ?Sized + for<'a> TypeNameable<'a, 'static> + Send> MockIndirect for Box<T> { + impl MockIndirect for MockValueVisitor { fn indirect(&self) -> IndirectLtAny<'_, 'static, Ref> { - IndirectLtAny::new(self) + IndirectLtAny::new::<DynValue<'static, DynOwnedStatic<'static, i32>, Blocking>>( + self as _, + ) } - fn indirect_mut(&mut self) -> IndirectLtAny<'_, 'static, Mut> { - IndirectLtAny::new(self) + fn indirect_mut<'a: 'b, 'b>(&'a mut self) -> IndirectLtAny<'b, 'static, Mut> { + IndirectLtAny::<'b, 'static, Mut>::new::< + DynValue<'static, DynOwnedStatic<'static, i32>, Blocking>, + >(self as _) } } + // pub struct IndirectBox<'a, 'ctx>(IndirectLtAny<'a, 'ctx, Boxed>); + // + // impl MockIndirect for IndirectBox + // { + // fn indirect<'a>(&'a self) -> IndirectLtAny<'a, 'static, Ref> { + // // let x: &MaybeSized::T<'a, 'static, T> = &*self.0; + // // IndirectLtAny::<'a, 'static, Ref>::new::<T>(x) + // todo!() + // } + // + // fn indirect_mut<'a>(&'a mut self) -> IndirectLtAny<'a, 'static, Mut> { + // let x: &'a mut MaybeSized::T<'static, 'static, T> = &mut *self.0; + // IndirectLtAny::<'static, 'static, Mut>::new::<T>(x) + // } + // } + impl<Seed: Send, Value: Send, Error: Send> BuilderTypes for MockBuilder<Seed, Value, Error> { type Seed = Seed; @@ -117,7 +146,9 @@ pub mod test { } } - impl<Seed: Send, Value: Send, Error: Send, E: Effect<'static>> Builder<'static, E> for MockBuilder<Seed, Value, Error> { + impl<Seed: Send, Value: Send, Error: Send, E: Effect<'static>> Builder<'static, E> + for MockBuilder<Seed, Value, Error> + { fn from_seed<'a>(seed: Self::Seed) -> Future<'a, 'static, Self, E> where Self: 'a, @@ -148,10 +179,10 @@ pub mod test { self.lookup().get(&id).map(|x| x.indirect()) } - fn upcast_to_id_mut<'a>( + fn upcast_to_id_mut<'a: 'b, 'b>( &'a mut self, id: LtTypeId<'static>, - ) -> Option<IndirectLtAny<'a, 'static, Mut>> + ) -> Option<IndirectLtAny<'b, 'static, Mut>> where 'static: 'a, { @@ -165,7 +196,7 @@ pub mod test { } } - impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<i32>, E> for MockValueVisitor { + impl<'ctx, E: Effect<'ctx>> Value<'ctx, DynOwnedStatic<'ctx, i32>, E> for MockValueVisitor { fn visit<'a>(&'a mut self, value: OwnedStatic<i32>) -> Future<'a, 'ctx, Flow, E> { E::ready(self.private_visit(value)) } @@ -176,40 +207,64 @@ pub mod test { let _lock = MockBuilder::<(), (), ()>::lock_context(); let ctx = MockBuilder::<(), (), ()>::private_from_seed_context(); + // Expect one mock builder to be made from the from_seed static method; ctx.expect().once().returning(|_| { let mut mock = MockBuilder::new(); - mock.expect_lookup_mut().returning(|| { - let mut map = HashMap::<_, Box<dyn MockIndirect>>::new(); + // Expect that we will lookup one trait on the visitor. + mock.expect_lookup_mut().once().returning(|| { + let mut map = HashMap::<LtTypeId<'static>, Box<dyn MockIndirect>>::new(); + + let mut mock = MockValueVisitor::new(); + + // Expect that we will pass the value 42 to the visitor. + mock.expect_private_visit() + .once() + .with(eq(OwnedStatic(42))) + .return_const(Flow::Done); + // This mock will be for the value protocol. map.insert( - LtTypeId::of::<DynValue<'_, 'static, OwnedStatic<i32>, Blocking>>(), - Box::new(Box::new(MockValueVisitor::new()) as Box<DynValue<'_, 'static, OwnedStatic<i32>, Blocking>>) + LtTypeId::of::<DynValue<'static, DynOwnedStatic<'static, i32>, Blocking>>(), + Box::new(mock), ); map }); - mock.expect_private_build().once().returning(|| { - Ok(()) - }); + mock.expect_private_build().once().returning(|| Ok(())); mock }); + // Create a mock builder using the static from_seed method. let mut builder = Spin::block_on(<MockBuilder as Builder<Blocking>>::from_seed(())); { + // Get the mock builder as a visitor. let visitor = <MockBuilder as Builder<Blocking>>::as_visitor(&mut builder); - let x = visitor.upcast_to_id_mut(LtTypeId::of::<DynValue<'_, '_, OwnedStatic<i32>, Blocking>>()).unwrap(); - let Ok(x) = x.downcast::<DynValue<'_, '_, OwnedStatic<i32>, Blocking>>() else { + // Upcast the mock visitor into a trait object for the value protocol. + // This resolves to one of the values in the hashmap above and not the builder itself. + let x = visitor + .upcast_to_id_mut(LtTypeId::of::< + DynValue<'_, DynOwnedStatic<'_, i32>, Blocking>, + >()) + .unwrap(); + + // Finish the upcast by downcasting to the trait object. + let Ok(x) = x.downcast::<DynValue<'_, DynOwnedStatic<'_, i32>, Blocking>>() else { panic!(); }; - Spin::block_on(x.visit(OwnedStatic(42))); + + // Use the visit method on the mock visitor. + assert_eq!(Spin::block_on(x.visit(OwnedStatic(42))), Flow::Done); } - let x = <MockBuilder as Builder<Blocking>>::build(builder); - todo!(); + // Finish building the mock builder. + assert_eq!( + Spin::block_on(<MockBuilder as Builder<Blocking>>::build(builder)).unwrap(), + () + ); } } |