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
pub struct Constrain;
pub unsafe trait TypeEq<A, B> {
fn as_eq(&self, a: A) -> B;
}
unsafe impl<A> TypeEq<A, A> for Constrain {
fn as_eq(&self, a: A) -> A { a }
}
pub trait Has<Prop> {
type Val;
fn get<P>(&self) -> &Self::Val
where
Constrain: TypeEq<Prop, P>;
}
#[cfg(test)]
mod tests {
use ::*;
#[test]
fn test_type_level_accessors() {
struct X;
struct Y;
struct Point<T> { x: T, y: T }
impl<T: Copy> Has<X> for Point<T> {
type Val = T;
fn get<P>(&self) -> &Self::Val
where
Constrain: TypeEq<X, P>
{
&self.x
}
}
impl<T: Copy> Has<Y> for Point<T> {
type Val = T;
fn get<P>(&self) -> &Self::Val
where
Constrain: TypeEq<Y, P>
{
&self.y
}
}
let p = Point { x: 3, y: 5 };
assert_eq!(&3, p.get::<X>());
assert_eq!(&5, p.get::<Y>());
}
#[test]
fn test_as_eq() {
struct Pair<A, B> {
a: A,
b: B,
}
impl<A: Copy, B: Copy> Pair<A, B> {
fn to_vec(&self) -> Vec<A> where Constrain: TypeEq<B, A> {
vec![self.a, Constrain.as_eq(self.b)]
}
}
let p = Pair { a: 1, b: 2 };
let v = p.to_vec();
assert_eq!(vec![1, 2], v);
}
}