recursive_variadic/
lib.rs1use std::any::{Any, TypeId};
6use std::mem;
7
8pub trait Key {
9 type Value: Any;
10}
11
12pub trait RecursiveVariadic {
14 fn get<N: Key>(&self) -> Option<&N::Value>;
16 fn get_mut<N: Key>(&mut self) -> Option<&mut N::Value>;
18 fn and<N: Key>(self, val: N::Value) -> Entry<N, Self> where Self: Sized {
20 Entry {
21 data: val,
22 parent: self,
23 }
24 }
25 fn and_default<N: Key>(self) -> Entry<N, Self>
27 where N::Value: Default, Self: Sized {
28 self.and(N::Value::default())
29 }
30}
31
32pub type Empty = ();
34impl RecursiveVariadic for Empty {
35 fn get<N: Key>(&self) -> Option<&N::Value> { None }
36 fn get_mut<N: Key>(&mut self) -> Option<&mut N::Value> { None }
37}
38
39pub struct Entry<T: Key, R> {
41 data: T::Value,
42 parent: R,
43}
44
45impl<T: Key, R: RecursiveVariadic> RecursiveVariadic for Entry<T, R> {
46 fn get<N: Key>(&self) -> Option<&N::Value> {
47 if TypeId::of::<N::Value>() == TypeId::of::<T::Value>() {
48 Some(unsafe { mem::transmute(&self.data) })
49 } else {
50 self.parent.get::<N>()
51 }
52 }
53 fn get_mut<N: Key>(&mut self) -> Option<&mut N::Value> {
54 if TypeId::of::<N::Value>() == TypeId::of::<T::Value>() {
55 Some(unsafe { mem::transmute(&mut self.data) })
56 } else {
57 self.parent.get_mut::<N>()
58 }
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use std::any::Any;
65
66 use super::*;
67
68 #[test]
69 fn it_works() {
70 impl Key for i32 { type Value = i32; }
71 impl Key for usize { type Value = Vec<usize>; }
72 impl Key for bool { type Value = bool; }
73 impl Key for &'static str { type Value = &'static str; }
74
75 let mut thing = ().and::<i32>(23).and_default::<usize>().and::<&'static str>("Hello!");
76 thing.get_mut::<usize>().unwrap().push(1);
77 assert!(thing.get::<i32>().is_some());
78 assert!(thing.get::<&'static str>().is_some());
79 assert!(thing.get::<bool>().is_none());
80 }
81}