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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
use TokenStream;
use ;
/// Proc. macro to derive [`EnumRef`] trait for the Rust `enum`.
///
/// This generates a new `enum` that mirrors all variants of the
/// original `enum` type but wraps all variant field in a shared
/// reference.
/// Furthermore it implement the [`EnumRef`] trait for the original
/// `enum` in order to make the generated `enum` accessible.
///
/// # Example
///
/// ```
/// use enum_ref::EnumRef;
///
/// #[derive(EnumRef)]
/// #[repr(u8)] // Rust requires this for `B = 42`
/// enum Test {
/// A,
/// B = 42,
/// C(i32),
/// D(i32, i64),
/// E { a: i32 },
/// F { a: i32, b: i64 },
/// }
///
/// // Access and name the generated `enum` as follows:
/// type TestRef<'a> = <Test as EnumRef>::Ref<'a>;
///
/// // Creates reference wrappers of `enum` instances as follows:
/// let test = Test::C(42);
/// let test_ref: TestRef = <Test as EnumRef>::as_ref(&test);
/// match (&test, test_ref) {
/// (Test::C(a0), TestRef::C(a1)) => assert_eq!(a0, a1),
/// _ => panic!("something wen't wrong ..."),
/// }
/// ```
///
/// The `#[derive(EnumRef)]` in the above example will generate roughly the following Rust code.
///
/// ```
/// # #[repr(u8)] // Rust requires this for `B = 42`
/// # enum Test {
/// # A,
/// # B = 42,
/// # C(i32),
/// # D(i32, i64),
/// # E { a: i32 },
/// # F { a: i32, b: i64 },
/// # }
/// #
/// const _: () = {
/// #[derive(::core::fmt::Debug)]
/// #[repr(u8)]
/// pub enum TestRef<'__enum_ref_lt> {
/// A,
/// B = 42,
/// C(&'__enum_ref_lt i32),
/// D(&'__enum_ref_lt i32, &'__enum_ref_lt i64),
/// E {
/// a: &'__enum_ref_lt i32,
/// },
/// F {
/// a: &'__enum_ref_lt i32,
/// b: &'__enum_ref_lt i64,
/// },
/// }
///
/// impl ::enum_ref::EnumRef for Test {
/// type Ref<'__enum_ref_lt> where Self: '__enum_ref_lt =
/// TestRef<'__enum_ref_lt> where Self: '__enum_ref_lt;
/// fn as_ref(&self) -> <Self as ::enum_ref::EnumRef>::Ref<'_> {
/// type __enum_ref_EnumRef_Ref<'__enum_ref_lt> =
/// <Test as ::enum_ref::EnumRef>::Ref<'__enum_ref_lt>;
/// match self {
/// Self::A => __enum_ref_EnumRef_Ref::A,
/// Self::B => __enum_ref_EnumRef_Ref::B,
/// Self::C(_0) => __enum_ref_EnumRef_Ref::C(_0),
/// Self::D(_0, _1) => __enum_ref_EnumRef_Ref::D(_0, _1),
/// Self::E { a } => __enum_ref_EnumRef_Ref::E { a },
/// Self::F { a, b } => __enum_ref_EnumRef_Ref::F { a, b },
/// }
/// }
/// }
/// };
/// ```
/// Proc. macro to derive [`EnumMut`] trait for the Rust `enum`.
///
/// This generates a new `enum` that mirrors all variants of the
/// original `enum` type but wraps all variant field in an exclusive
/// reference.
/// Furthermore it implement the [`EnumMut`] trait for the original
/// `enum` in order to make the generated `enum` accessible.
///
/// # Example
///
/// ```
/// use enum_ref::EnumMut;
///
/// # #[derive(Clone)]
/// #[derive(EnumMut)]
/// #[repr(u8)] // Rust requires this for `B = 42`
/// enum Test {
/// A,
/// B = 42,
/// C(i32),
/// D(i32, i64),
/// E { a: i32 },
/// F { a: i32, b: i64 },
/// }
///
/// // Access and name the generated `enum` as follows:
/// type TestMut<'a> = <Test as EnumMut>::Mut<'a>;
///
/// // Creates reference wrappers of `enum` instances as follows:
/// let mut test0 = Test::C(42);
/// let mut test1 = test0.clone();
/// let test_ref: TestMut = <Test as EnumMut>::as_mut(&mut test0);
/// match (&mut test1, test_ref) {
/// (Test::C(a0), TestMut::C(a1)) => assert_eq!(a0, a1),
/// _ => panic!("something wen't wrong ..."),
/// }
/// ```
///
/// The `#[derive(EnumMut)]` in the above example will generate roughly the following Rust code.
///
/// ```
/// # #[repr(u8)] // Rust requires this for `B = 42`
/// # enum Test {
/// # A,
/// # B = 42,
/// # C(i32),
/// # D(i32, i64),
/// # E { a: i32 },
/// # F { a: i32, b: i64 },
/// # }
/// #
/// const _: () = {
/// #[derive(::core::fmt::Debug)]
/// #[repr(u8)]
/// pub enum TestMut<'__enum_ref_lt> {
/// A,
/// B = 42,
/// C(&'__enum_ref_lt mut i32),
/// D(&'__enum_ref_lt mut i32, &'__enum_ref_lt mut i64),
/// E {
/// a: &'__enum_ref_lt mut i32,
/// },
/// F {
/// a: &'__enum_ref_lt mut i32,
/// b: &'__enum_ref_lt mut i64,
/// },
/// }
///
/// impl ::enum_ref::EnumMut for Test {
/// type Mut<'__enum_ref_lt> where Self: '__enum_ref_lt =
/// TestMut<'__enum_ref_lt> where Self: '__enum_ref_lt;
/// fn as_mut(&mut self) -> <Self as ::enum_ref::EnumMut>::Mut<'_> {
/// type __enum_ref_EnumMut_Mut<'__enum_ref_lt> =
/// <Test as ::enum_ref::EnumMut>::Mut<'__enum_ref_lt>;
/// match self {
/// Self::A => __enum_ref_EnumMut_Mut::A,
/// Self::B => __enum_ref_EnumMut_Mut::B,
/// Self::C(_0) => __enum_ref_EnumMut_Mut::C(_0),
/// Self::D(_0, _1) => __enum_ref_EnumMut_Mut::D(_0, _1),
/// Self::E { a } => __enum_ref_EnumMut_Mut::E { a },
/// Self::F { a, b } => __enum_ref_EnumMut_Mut::F { a, b },
/// }
/// }
/// }
/// };
/// ```