use effectful::{
effective::Effective,
bound::{Bool, IsSend, IsSync},
environment::{Environment, NativeForm, DynBind},
forward_send_sync,
};
use mockall::mock;
use treaty::{
any::{indirect, AnyTrait, AnyTraitObject, TypeNameId},
protocol::DynVisitor,
Builder, BuilderTypes, Walker,
};
mock! {
pub Walker<Output, Error, E: Environment> {
pub fn walk<'a, 'ctx>(self, visitor: DynVisitor<'a, 'ctx, E>) -> Result<Output, Error>;
pub fn traits(&self, id: TypeNameId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx, E>>>;
pub fn traits_mut(&mut self, id: TypeNameId) -> &mut Option<Box<dyn for<'ctx> AnyTrait<'ctx, E>>>;
}
}
forward_send_sync!({Output, Error} {} {E: (Environment)} MockWalker<Output, Error, E>);
impl<'ctx, Output: DynBind<E>, Error: DynBind<E> + core::fmt::Debug, E: Environment>
Walker<'ctx, E> for MockWalker<Output, Error, E>
{
type Error = Error;
type Output = Output;
fn walk<'a: 'c, 'c>(
self,
visitor: DynVisitor<'a, 'ctx, E>,
) -> NativeForm<'c, Result<Self::Output, Self::Error>, E>
where
Self: 'c,
{
E::value(self.walk(visitor)).cast()
}
}
impl<'ctx, Output: DynBind<E>, Error: DynBind<E>, E: Environment> AnyTrait<'ctx, E> for MockWalker<Output, Error, E> {
fn upcast_to_id<'a>(
&'a self,
id: TypeNameId,
) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, E>>
where
'ctx: 'a,
{
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, E>>
where
'ctx: 'a,
{
self.traits_mut(id)
.as_mut()
.and_then(|t| t.upcast_to_id_mut(id))
}
type Available = () where Self: Sized;
}