Diffstat (limited to 'src/build.rs')
-rw-r--r--src/build.rs103
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(),
+ ()
+ );
}
}