static_context/
lib.rs

1// -*- coding: utf-8 -*-
2// ------------------------------------------------------------------------------------------------
3// Copyright © 2020, Douglas Creager.
4//
5// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
6// in compliance with the License.  You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software distributed under the
11// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12// express or implied.  See the License for the specific language governing permissions and
13// limitations under the License.
14// ------------------------------------------------------------------------------------------------
15
16use 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;