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))
}
}