use effectful::{
bound::{Bool, IsSend, IsSync},
effective::{Effective, Canonical},
environment::{Environment},
forward_send_sync,
higher_ranked::WithLt,
};
use mockall::mock;
use treaty::{
any::{type_name, AnyTrait, MutAnyUnsized, WithLtTypeId, trait_by_id},
protocol::{
visitor::VisitResult,
walker::hint::{DynVisitorWith, Hint, HintMeta},
DynVisitor,
},
Flow,
};
pub type KnownFactory<P> = for<'a, 'ctx> fn(
&'ctx (),
&'a WithLt<'a, <P as HintMeta>::Hint>,
) -> Result<WithLt<'a, <P as HintMeta>::Known>, ()>;
mock! {
pub HintWalker<P: ?Sized + HintMeta> {
pub fn hint<'a, 'b, 'c, 'lt, 'ctx>(&'a mut self, visitor: DynVisitorWith<'b, 'lt, 'ctx, P>, hint: WithLt<'c, P::Hint>) -> VisitResult;
pub fn known(&self) -> KnownFactory<P>;
}
}
forward_send_sync!({} {} {P: (?Sized + HintMeta + Send)} MockHintWalker<P>);
impl<'lt, 'ctx: 'lt, P: ?Sized + HintMeta + Send> AnyTrait<'lt, 'ctx> for MockHintWalker<P> {
fn upcast_by_id_mut<'a>(
&'a mut self,
id: WithLtTypeId<'lt, 'ctx>,
) -> Option<MutAnyUnsized<'a, 'lt, 'ctx>>
where
'lt: 'a,
{
trait_by_id!(&mut self, id, {
type Impls = (dyn Hint<P>);
});
None
}
}
// any_trait! {
// impl['ctx, P][E] MockHintWalker<P> = [
// HintProto<P>
// ] where
// E: Environment,
// P: HintMeta<Effect = E>,
// }
impl<'ctx, P: ?Sized + HintMeta + Send> Hint<'ctx, P> for MockHintWalker<P> {
fn hint<'this: 'e, 'visitor: 'e, 'lt: 'e, 'hint: 'e, 'e>(
&'this mut self,
visitor: DynVisitorWith<'visitor, 'lt, 'ctx, P>,
hint: WithLt<'hint, <P as HintMeta>::Hint>,
) -> Canonical<'e, VisitResult, <P>::Env>
where
'ctx: 'this + 'visitor + 'hint,
{
P::Env::value(self.hint(visitor, hint)).cast()
}
fn known<'a>(
&'a mut self,
hint: &'a WithLt<'a, <P as HintMeta>::Hint>,
) -> Canonical<'a, Result<WithLt<'a, <P as HintMeta>::Known>, ()>, <P>::Env>
where
WithLt<'a, <P as HintMeta>::Known>: effectful::bound::DynBind<<P>::Env>,
{
todo!()
}
// fn hint<'this, 'visitor, 'hint, 'e>(
// &'this mut self,
// visitor: DynVisitorWith<'visitor, 'ctx, P>,
// hint: WithLt<'hint, P>,
// ) -> Canonical<'e, VisitResult, P::Effect>
// where
// 'ctx: 'this + 'visitor + 'hint + 'e,
// {
// P::Effect::value(self.hint(visitor, hint)).cast()
// }
//
// fn known<'a>(
// &'a mut self,
// hint: &'a WithLt<'a, P::Hint>,
// ) -> Canonical<'a, Result<WithLt<'a, P::Known>, ()>, P::Effect> {
// P::Effect::value(Self::known(self)(&(), hint)).cast()
// }
}