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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
pub trait Mapping {
type To<X>;
type Arguments;
fn create<X>(arguments: &Self::Arguments) -> Self::To<X>;
}
pub struct _EmptyMapping;
impl Mapping for _EmptyMapping {
type To<X> = ();
type Arguments = ();
fn create<X>(_: &Self::Arguments) -> Self::To<X> {}
}
pub trait _RecordType<R>
where
Self: Sized, {
type Record<X: Mapping>;
fn get<X: Mapping>(record: &Self::Record<X>) -> &X::To<Self>;
fn get_mut<X: Mapping>(record: &mut Self::Record<X>) -> &mut X::To<Self>;
}
pub trait _Record<X: Mapping, U, T: _RecordType<U>> {
fn _get(&self) -> &X::To<T>;
fn _get_mut(&mut self) -> &mut X::To<T>;
}
impl<X: Mapping, U, T: _RecordType<U>> _Record<X, U, T> for T::Record<X> {
#[inline]
fn _get(&self) -> &X::To<T> {
T::get::<X>(self)
}
#[inline]
fn _get_mut(&mut self) -> &mut X::To<T> {
T::get_mut::<X>(self)
}
}
#[macro_export]
macro_rules! record {
($record_name:ident { $($record_contents:ident),+ $(,)? }) => {
#[allow(non_snake_case)]
pub struct $record_name<X: ::type_record::Mapping> {
$($record_contents: X::To<$record_contents>,)+
}
$(impl ::type_record::_RecordType<$record_name<::type_record::_EmptyMapping>> for $record_contents {
type Record<X: ::type_record::Mapping> = $record_name<X>;
#[inline]
fn get<X: ::type_record::Mapping>(record: &$record_name<X>) -> &X::To<Self> {
&record.$record_contents
}
#[inline]
fn get_mut<X: ::type_record::Mapping>(record: &mut $record_name<X>) -> &mut X::To<Self> {
&mut record.$record_contents
}
})+
impl<X: ::type_record::Mapping> $record_name<X> {
#[inline]
#[doc = "Creates a new record using the arguments provided."]
pub fn new(arguments: X::Arguments) -> Self {
$record_name {
$($record_contents: X::create::<$record_contents>(&arguments),)+
}
}
#[inline]
#[doc = "Gets an immutable reference to the value with key `T`."]
pub fn get<
T: ::type_record::_RecordType<$record_name<::type_record::_EmptyMapping>>
>(&self) -> &X::To<T> where Self: ::type_record::_Record<X, $record_name<::type_record::_EmptyMapping>, T> {
<Self as ::type_record::_Record<X, $record_name<::type_record::_EmptyMapping>, T>>::_get(self)
}
#[inline]
#[doc = "Gets a mutable reference to the value with key `T`."]
pub fn get_mut<
T: ::type_record::_RecordType<$record_name<::type_record::_EmptyMapping>>
>(&mut self) -> &mut X::To<T> where Self: ::type_record::_Record<X, $record_name<::type_record::_EmptyMapping>, T> {
<Self as ::type_record::_Record<X, $record_name<::type_record::_EmptyMapping>, T>>::_get_mut(self)
}
}
};
}