1#[macro_export]
17#[rustfmt::skip]
18#[cfg_attr(cargo_primary_package, doc(hidden))]
19macro_rules! capture_first {
20 (block $first:block $(, $tail:block)* $(,)?) => { $first };
21 (expr $first:expr $(, $tail:expr)* $(,)?) => { $first };
22 (ident $first:ident $(, $tail:ident)* $(,)?) => { $first };
23 (literal $first:literal $(, $tail:literal)* $(,)?) => { $first };
24 (meta $first:meta $(, $tail:meta)* $(,)?) => { $first };
25 (pat $first:pat $(, $tail:pat)* $(,)?) => { $first };
26 (path $first:path $(, $tail:path)* $(,)?) => { $first };
27 (ty $first:ty $(, $tail:ty)* $(,)?) => { $first };
28 (tt $first:tt $(, $tail:tt)* $(,)?) => { $first };
29}
30#[doc(inline)]
31pub use capture_first;
32
33#[macro_export]
35#[rustfmt::skip]
36#[cfg_attr(cargo_primary_package, doc(hidden))]
37macro_rules! capture_tail_tuple {
38 (block $first:block, $($tail:block),* $(,)?) => { ($($tail),*) };
39 (expr $first:expr, $($tail:expr),* $(,)?) => { ($($tail),*) };
40 (ident $first:ident, $($tail:ident),* $(,)?) => { ($($tail),*) };
41 (literal $first:literal, $($tail:literal),* $(,)?) => { ($($tail),*) };
42 (meta $first:meta, $($tail:meta),* $(,)?) => { ($($tail),*) };
43 (pat $first:pat, $($tail:pat),* $(,)?) => { ($($tail),*) };
44 (path $first:path, $($tail:path),* $(,)?) => { ($($tail),*) };
45 (tt $first:tt, $($tail:tt),* $(,)?) => { ($($tail),*) };
46 (ty $first:ty, $($tail:ty),* $(,)?) => { ($($tail),*) };
47
48 ($cat:tt $first:tt) => { () };
50}
51#[doc(inline)]
52pub use capture_tail_tuple;
53
54#[doc(hidden)]
72#[macro_export]
73#[rustfmt::skip]
74macro_rules! _capture_last {
75 (block $first:block) => { $first };
77 (expr $first:expr) => { $first };
78 (ident $first:ident) => { $first };
79 (literal $first:literal) => { $first };
80 (meta $first:meta) => { $first };
81 (pat $first:pat) => { $first };
82 (path $first:path) => { $first };
83 (tt $first:tt) => { $first };
84 (ty $first:ty) => { $first };
85
86 (block $first:block, $($tail:block),* $(,)?) => {
88 $crate::capture_last!(block $($tail),*) };
89 (expr $first:expr, $($tail:expr),* $(,)?) => {
90 $crate::capture_last!(expr $($tail),*) };
91 (ident $first:ident, $($tail:ident),* $(,)?) => {
92 $crate::capture_last!(ident $($tail),*) };
93 (literal $first:literal, $($tail:literal),* $(,)?) => {
94 $crate::capture_last!(literal $($tail),*) };
95 (meta $first:meta, $($tail:meta),* $(,)?) => {
96 $crate::capture_last!(meta $($tail),*) };
97 (pat $first:pat, $($tail:pat),* $(,)?) => {
98 $crate::capture_last!(pat $($tail),*) };
99 (path $first:path, $($tail:path),* $(,)?) => {
100 $crate::capture_last!(path $($tail),*) };
101 (tt $first:tt, $($tail:tt),* $(,)?) => {
102 $crate::capture_last!(tt $($tail),*) };
103 (ty $first:ty, $($tail:ty),* $(,)?) => {
104 $crate::capture_last!(ty $($tail),*) };
105}
106#[doc(inline)]
107pub use _capture_last as capture_last;
108
109#[cfg(test)]
110mod tests {
111 pub use super::*;
112
113 #[test]
114 fn capture_first() {
115 assert_eq![{ 2 }, capture_first!(block { 1 + 1 }, { loop {} }, { 3 * 2 })];
116
117 assert_eq![5, capture_first!(expr 5, "a", if a == 3 {}, 4 + 3)];
118
119 let my_var = ();
120 assert_eq![my_var, capture_first!(ident my_var, another_var)];
121
122 assert_eq!["32", capture_first!(literal "32", 100, '€')];
123
124 assert_eq!['%', capture_first!(tt '%', "$", 3, {}, something)];
125
126 let captured = 1 as capture_first!(ty i32, u64, bool, f32);
127 assert_eq![1_i32, captured];
128
129 assert_eq!(5, capture_first!(expr 5));
132 assert_eq!(my_var, capture_first!(ident my_var));
133 assert_eq!('€', capture_first!(literal '€'));
134 }
135
136 #[test]
137 fn capture_tail_tuple() {
138 assert_eq![(6, "a"), capture_tail_tuple!(expr if a == 3 {}, 6, "a")];
139
140 let (my_var, another_var) = ((), ());
141 assert_eq![another_var, capture_tail_tuple!(ident my_var, another_var)];
142
143 assert_eq![(my_var, another_var), capture_tail_tuple!(tt { token }, my_var, another_var)];
144
145 struct TestStruct<T>(T);
146 let _instance: TestStruct<capture_tail_tuple!(ty i32, f32, bool)> = TestStruct((2.5, true));
147 }
148
149 #[test]
150 fn capture_last() {
151 assert_eq![{ 6 }, capture_last!(block { 1 + 1 }, { loop {} }, { 3 * 2 })];
152
153 assert_eq![7, capture_last!(expr 5, "a", if a == 3 {}, 4 + 3)];
154
155 let (my_var, another_var) = ((), ());
156 assert_eq![another_var, capture_last!(ident my_var, another_var)];
157
158 assert_eq!['€', capture_last!(literal "32", 100, '€')];
159
160 let something = ();
161 assert_eq![something, capture_last!(tt '%', "$", 3, {}, something)];
162
163 let captured = 1.3 as capture_last!(ty i32, u64, bool, f32);
164 assert_eq![1.3_f32, captured];
165
166 assert_eq!(5, capture_last!(expr 5));
169 assert_eq!(my_var, capture_last!(ident my_var));
170 assert_eq!('€', capture_last!(literal '€'));
171 }
172}