use core::fmt::{Debug, Display};
use mockall::mock;
use treaty::{
any::{indirect, AnyTrait, AnyTraitObject, TypeNameId},
effect::{Effect, Effective, ErasedEffective},
protocol::{AsVisitor, DynVisitor},
Builder, BuilderTypes,
};
use crate::common::{ContextLock, StaticTypeMap};
use self::__mock_MockBuilder::__from_seed::Context;
use super::ContextGuard;
#[derive(Debug)]
pub struct EmptyError;
impl Display for EmptyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "EmptyError")
}
}
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 + Display + Debug> 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 + Display + Debug,
E: Effect,
> Builder<'ctx, E> for MockBuilder<Seed, Value, Error>
{
fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E>
where
Self: 'a,
{
E::ready(Self::from_seed(seed))
}
fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a,
{
E::ready(self.build())
}
}
impl<'ctx, Seed: Send + Sync, Value: Send + Sync, Error: Send + Sync + Display + Debug>
AsVisitor<'ctx> for MockBuilder<Seed, Value, Error>
{
fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx>
where
'ctx: 'a,
{
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))
}
type Available = () where Self: Sized;
}