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
use std::any::{Any, TypeId};
use std::mem;
pub trait Key {
type Value: Any;
}
pub trait RecursiveVariadic {
fn get<N: Key>(&self) -> Option<&N::Value>;
fn get_mut<N: Key>(&mut self) -> Option<&mut N::Value>;
fn and<N: Key>(self, val: N::Value) -> Entry<N, Self> where Self: Sized {
Entry {
data: val,
parent: self,
}
}
fn and_default<N: Key>(self) -> Entry<N, Self>
where N::Value: Default, Self: Sized {
self.and(N::Value::default())
}
}
pub type Empty = ();
impl RecursiveVariadic for Empty {
fn get<N: Key>(&self) -> Option<&N::Value> { None }
fn get_mut<N: Key>(&mut self) -> Option<&mut N::Value> { None }
}
pub struct Entry<T: Key, R> {
data: T::Value,
parent: R,
}
impl<T: Key, R: RecursiveVariadic> RecursiveVariadic for Entry<T, R> {
fn get<N: Key>(&self) -> Option<&N::Value> {
if TypeId::of::<N::Value>() == TypeId::of::<T::Value>() {
Some(unsafe { mem::transmute(&self.data) })
} else {
self.parent.get::<N>()
}
}
fn get_mut<N: Key>(&mut self) -> Option<&mut N::Value> {
if TypeId::of::<N::Value>() == TypeId::of::<T::Value>() {
Some(unsafe { mem::transmute(&mut self.data) })
} else {
self.parent.get_mut::<N>()
}
}
}
#[cfg(test)]
mod tests {
use std::any::Any;
use super::*;
#[test]
fn it_works() {
impl Key for i32 { type Value = i32; }
impl Key for usize { type Value = Vec<usize>; }
impl Key for bool { type Value = bool; }
impl Key for &'static str { type Value = &'static str; }
let mut thing = ().and::<i32>(23).and_default::<usize>().and::<&'static str>("Hello!");
thing.get_mut::<usize>().unwrap().push(1);
assert!(thing.get::<i32>().is_some());
assert!(thing.get::<&'static str>().is_some());
assert!(thing.get::<bool>().is_none());
}
}