1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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()
    // }
}