1use std::marker::PhantomData;
17
18pub struct Context<Stack>(Stack);
19
20impl Context<()> {
21 pub fn root() -> () {
22 ()
23 }
24}
25
26impl<Stack> Context<Stack> {
27 pub fn stack(&self) -> &Stack {
28 &self.0
29 }
30}
31
32pub trait ContextParent: Sized {
33 fn add<Next>(self, next: Next) -> ContextStack<Next, Self>;
34 fn seal(self) -> Context<Self>;
35}
36
37impl ContextParent for () {
38 fn add<Next>(self, next: Next) -> ContextStack<Next, Self> {
39 ContextStack {
40 head: next,
41 tail: self,
42 }
43 }
44
45 fn seal(self) -> Context<Self> {
46 Context(self)
47 }
48}
49
50impl<H, T> ContextParent for ContextStack<H, T> {
51 fn add<Next>(self, next: Next) -> ContextStack<Next, Self> {
52 ContextStack {
53 head: next,
54 tail: self,
55 }
56 }
57
58 fn seal(self) -> Context<Self> {
59 Context(self)
60 }
61}
62
63pub struct ContextStack<Head, Tail> {
64 pub head: Head,
65 pub tail: Tail,
66}
67
68pub struct Next<T>(PhantomData<T>);
69
70pub trait Has<Unit, Proof> {
71 fn get_unit(&self) -> &Unit;
72 fn get_unit_mut(&mut self) -> &mut Unit;
73}
74
75impl<Stack, Unit, Proof> Has<Unit, Proof> for Context<Stack>
76where
77 Stack: Has<Unit, Proof>,
78{
79 fn get_unit(&self) -> &Unit {
80 self.0.get_unit()
81 }
82
83 fn get_unit_mut(&mut self) -> &mut Unit {
84 self.0.get_unit_mut()
85 }
86}
87
88impl<Unit, Tail> Has<Unit, ()> for ContextStack<Unit, Tail> {
89 fn get_unit(&self) -> &Unit {
90 &self.head
91 }
92
93 fn get_unit_mut(&mut self) -> &mut Unit {
94 &mut self.head
95 }
96}
97
98impl<Unit, Head, Tail, TailProof> Has<Unit, Next<TailProof>> for ContextStack<Head, Tail>
99where
100 Tail: Has<Unit, TailProof>,
101{
102 fn get_unit(&self) -> &Unit {
103 self.tail.get_unit()
104 }
105
106 fn get_unit_mut(&mut self) -> &mut Unit {
107 self.tail.get_unit_mut()
108 }
109}
110
111#[cfg(test)]
112mod tests;