Diffstat (limited to 'src/mock/builder.rs')
-rw-r--r--src/mock/builder.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/mock/builder.rs b/src/mock/builder.rs
new file mode 100644
index 0000000..31c1623
--- /dev/null
+++ b/src/mock/builder.rs
@@ -0,0 +1,99 @@
+use mockall::mock;
+
+use crate::{
+ any::{AnyTrait, IndirectLtAny, LtTypeId, Mut, Ref},
+ effect::{Effect, Future},
+ mock::{ContextLock, StaticTypeMap},
+ protocol::Visitor,
+ Builder, BuilderTypes,
+};
+
+use self::__mock_MockBuilder::__from_seed::Context;
+
+use super::ContextGuard;
+
+use crate::any::ForAnyTypeId;
+
+mock! {
+ pub Builder<Seed: 'static, Value: 'static, Error: 'static> {
+ pub fn from_seed(seed: Seed) -> Self;
+ pub fn build(self) -> Result<Value, Error>;
+
+ pub fn traits(&self, id: ForAnyTypeId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx> + Send>>;
+ pub fn traits_mut(&mut self, id: ForAnyTypeId) -> &mut Option<Box<dyn for<'ctx> AnyTrait<'ctx> + Send>>;
+ }
+}
+
+impl<Seed: Send, Value: Send, Error: Send> BuilderTypes for MockBuilder<Seed, Value, Error> {
+ type Seed = Seed;
+
+ type Error = Error;
+
+ type Value = Value;
+}
+
+impl<Seed: 'static, Value: 'static, Error: 'static> MockBuilder<Seed, Value, Error> {
+ pub fn lock_from_seed_context<'a>() -> ContextGuard<'a, Context<Seed, Value, Error>> {
+ static LOCKS: StaticTypeMap = StaticTypeMap::new();
+
+ LOCKS
+ .get_or_init(|| {
+ ContextLock::new(MockBuilder::from_seed_context(), |context| {
+ context.checkpoint()
+ })
+ })
+ .lock()
+ }
+}
+
+impl<'ctx, Seed: Send, Value: Send, Error: Send, E: Effect<'ctx>> Builder<'ctx, E>
+ for MockBuilder<Seed, Value, Error>
+{
+ #[track_caller]
+ fn from_seed<'a>(seed: Self::Seed) -> Future<'a, 'ctx, Self, E>
+ where
+ Self: 'a,
+ {
+ E::ready(Self::from_seed(seed))
+ }
+
+ #[track_caller]
+ fn build<'a>(self) -> Future<'a, 'ctx, Result<Self::Value, Self::Error>, E>
+ where
+ Self: 'a,
+ {
+ E::ready(self.build())
+ }
+
+ #[track_caller]
+ fn as_visitor(&mut self) -> Visitor<'_, 'ctx> {
+ self
+ }
+}
+
+impl<'ctx, Seed, Value, Error> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error> {
+ #[track_caller]
+ fn upcast_to_id<'a>(&'a self, id: LtTypeId<'ctx>) -> Option<IndirectLtAny<'a, 'ctx, Ref>>
+ where
+ 'ctx: 'a,
+ {
+ // Find the first trait handler that wants to upcast.
+ self.traits(id.as_type_id())
+ .as_ref()
+ .and_then(|t| t.upcast_to_id(id))
+ }
+
+ #[track_caller]
+ fn upcast_to_id_mut<'a: 'b, 'b>(
+ &'a mut self,
+ id: LtTypeId<'ctx>,
+ ) -> Option<IndirectLtAny<'b, 'ctx, Mut>>
+ where
+ 'ctx: 'a,
+ {
+ // Find the first trait handler that wants to upcast.
+ self.traits_mut(id.as_type_id())
+ .as_mut()
+ .and_then(|t| t.upcast_to_id_mut(id))
+ }
+}