use core::fmt::{Debug, Display};
use effectful::{
DynBind,
bound::{Bool, Dynamic, IsSend, IsSync},
effective::{Effective, Canonical},
environment::{Environment},
forward_send_sync, SendSync,
};
use mockall::mock;
use treaty::{
any::{AnyTrait, MutAnyUnsized, WithLtTypeId},
build::BuilderTypes,
protocol::{AsVisitor, DynVisitor},
Builder,
};
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: WithLtTypeId<'_, '_>) -> &Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>;
// pub fn traits_mut(&mut self, id: WithLtTypeId<'_, '_>) -> &mut Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>;
pub fn traits_mut(&mut self) -> &mut Box<dyn for<'a, 'ctx> FnMut(WithLtTypeId<'a, 'ctx>) -> Option<MutAnyUnsized<'a, 'a, 'ctx>> + Send>;
}
}
forward_send_sync!({Seed: ('static), Error: ('static)} {} {Value: ('static + Send), E: (Environment + Send)} 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<'lt, 'ctx, Seed: DynBind<E>, Value: Send, Error: DynBind<E> + Display + Debug, E: Environment + Send>
Builder<'lt, 'ctx, E> for MockBuilder<Seed, Value, Error, E>
where
Dynamic<Value>: DynBind<E>,
{
fn from_seed<'a>(seed: Self::Seed) -> Canonical<'a, Self, E>
where
Self: 'a,
{
E::value(Self::from_seed(seed)).cast()
}
fn build<'a>(self) -> Canonical<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
E::value(self.build().map(Dynamic)).cast()
}
}
impl<'lt, 'ctx, Seed, Value: Send, Error: Display + Debug, E: Environment + Send> AsVisitor<'lt, 'ctx, E>
for MockBuilder<Seed, Value, Error, E>
where
Seed: DynBind<E>,
Error: DynBind<E>,
Dynamic<Value>: DynBind<E>,
{
fn as_visitor(&mut self) -> DynVisitor<'_, 'lt, 'ctx, E> {
DynVisitor(self)
}
}
impl<'lt, 'ctx: 'lt, Seed, Value, Error, E: Environment> AnyTrait<'lt, 'ctx> for MockBuilder<Seed, Value, Error, E>
where
Seed: DynBind<E>,
Error: DynBind<E>,
Dynamic<Value>: DynBind<E>,
{
fn upcast_by_id<'a>(
&'a self,
id: treaty::any::WithLtTypeId<'lt, 'ctx>,
) -> Option<treaty::any::RefAnyUnsized<'a, 'lt, 'ctx>>
where
'lt: 'a,
{
let _id = id;
None
}
fn upcast_by_id_mut<'a>(
&'a mut self,
id: treaty::any::WithLtTypeId<'lt, 'ctx>,
) -> Option<treaty::any::MutAnyUnsized<'a, 'lt, 'ctx>>
where
'lt: 'a,
{
self.traits_mut()(id)
}
// 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;
}