use mockall::mock;
use treaty::{
any::{indirect, AnyTrait, AnyTraitObject, TypeNameId},
effect::{Effect, Future},
protocol::DynVisitor,
Builder, BuilderTypes,
};
use crate::common::{ContextLock, StaticTypeMap};
use self::__mock_MockBuilder::__from_seed::Context;
use super::ContextGuard;
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: TypeNameId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx> + Send + Sync>>;
pub fn traits_mut(&mut self, id: TypeNameId) -> &mut Option<Box<dyn for<'ctx> AnyTrait<'ctx> + Send + Sync>>;
}
}
impl<Seed: Send + Sync, Value: Send + Sync, Error: Send + Sync> 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 + Sync, Value: Send + Sync, Error: Send + Sync, E: Effect> Builder<'ctx, E>
for MockBuilder<Seed, Value, Error>
{
fn from_seed<'a>(seed: Self::Seed) -> Future<'a, Self, E>
where
Self: 'a,
{
E::ready(Self::from_seed(seed))
}
fn build<'a>(self) -> Future<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a,
{
E::ready(self.build())
}
fn as_visitor(&mut self) -> DynVisitor<'_, 'ctx> {
DynVisitor(self)
}
}
impl<'ctx, Seed, Value, Error> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error> {
fn upcast_to_id<'a>(&'a self, id: TypeNameId) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref>>
where
'ctx: 'a,
{
// Find the first trait handler that wants to upcast.
self.traits(id).as_ref().and_then(|t| t.upcast_to_id(id))
}
fn upcast_to_id_mut<'a>(
&'a mut self,
id: TypeNameId,
) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut>>
where
'ctx: 'a,
{
// Find the first trait handler that wants to upcast.
self.traits_mut(id)
.as_mut()
.and_then(|t| t.upcast_to_id_mut(id))
}
}