use core::fmt::{Debug, Display};
use effectful::{
bound::{Bool, Dynamic, DynamicShim, IsSend, IsSync}, effective::Effective, environment::{DynBind, Environment, NativeForm}, forward_send_sync, SendSync
};
use mockall::mock;
use treaty::{
any::{indirect, AnyTrait, AnyTraitObject, TypeNameId},
protocol::{AsVisitor, DynVisitor},
Builder, BuilderTypes,
};
use crate::common::{ContextLock, StaticTypeMap};
use super::ContextGuard;
use crate::common::builder::__mock_MockBuilder::__from_seed::Context;
#[derive(Debug, SendSync)]
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, E: Environment> {
pub fn from_seed(seed: Seed) -> Self;
pub fn build(self) -> Result<Value, Error>;
pub fn traits(&self, id: TypeNameId) -> &Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>;
pub fn traits_mut(&mut self, id: TypeNameId) -> &mut Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>;
}
}
forward_send_sync!({Seed: ('static), Error: ('static)} {} {Value: ('static), E: (Environment)} MockBuilder<Seed, Value, Error, E>);
impl<Seed, Value, Error: Display + Debug, E: Environment> BuilderTypes<E>
for MockBuilder<Seed, Value, Error, E>
where
Seed: DynBind<E>,
Dynamic<Value>: DynBind<E>,
Error: DynBind<E>,
{
type Seed = Seed;
type Error = Error;
type Output = Dynamic<Value>;
type Value = Value;
fn unwrap_output(output: Self::Output) -> Self::Value {
output.0
}
}
impl<Seed: 'static, Value: 'static, Error: 'static, E: Environment>
MockBuilder<Seed, Value, Error, E>
{
pub fn lock_from_seed_context<'a>() -> ContextGuard<'a, Context<Seed, Value, Error, E>> {
static LOCKS: StaticTypeMap = StaticTypeMap::new();
LOCKS
.get_or_init(|| {
ContextLock::new(MockBuilder::from_seed_context(), |context| {
context.checkpoint()
})
})
.lock()
}
}
impl<
'ctx,
Seed: DynBind<E>,
Value,
Error: DynBind<E> + Display + Debug,
E: Environment,
> Builder<'ctx, E> for MockBuilder<Seed, Value, Error, E>
where
Dynamic<Value>: DynBind<E>
{
fn from_seed<'a>(seed: Self::Seed) -> NativeForm<'a, Self, E>
where
Self: 'a,
{
E::value(Self::from_seed(seed)).cast()
}
fn build<'a>(self) -> NativeForm<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
E::value(self.build().map(Dynamic)).cast()
}
}
impl<'ctx, Seed, Value, Error: Display + Debug, E: Environment> AsVisitor<'ctx, E>
for MockBuilder<Seed, Value, Error, E>
where
Seed: DynBind<E>,
Error: DynBind<E>,
Dynamic<Value>: DynBind<E>
{
fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E>
where
'ctx: 'a,
{
DynVisitor(self)
}
}
impl<'ctx, Seed, Value, Error, E: Environment> AnyTrait<'ctx, E>
for MockBuilder<Seed, Value, Error, E>
where
Seed: DynBind<E>,
Error: DynBind<E>,
Dynamic<Value>: DynBind<E>,
{
fn upcast_to_id<'a>(
&'a self,
id: TypeNameId,
) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, E>>
where
'ctx: 'a,
{
// Find the first trait handler that wants to upcast.
self.traits(id).as_ref().and_then(|t| t.0.upcast_to_id(id))
}
fn upcast_to_id_mut<'a>(
&'a mut self,
id: TypeNameId,
) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut, E>>
where
'ctx: 'a,
{
// Find the first trait handler that wants to upcast.
self.traits_mut(id)
.as_mut()
.and_then(|t| t.0.upcast_to_id_mut(id))
}
type Available = () where Self: Sized;
}