]>
Commit | Line | Data |
---|---|---|
92a42be0 SL |
1 | /// A macro for defining #[cfg] if-else statements. |
2 | /// | |
3 | /// This is similar to the `if/elif` C preprocessor macro by allowing definition | |
4 | /// of a cascade of `#[cfg]` cases, emitting the implementation which matches | |
5 | /// first. | |
6 | /// | |
7 | /// This allows you to conveniently provide a long list #[cfg]'d blocks of code | |
8 | /// without having to rewrite each clause multiple times. | |
9 | macro_rules! cfg_if { | |
10 | ($( | |
11 | if #[cfg($($meta:meta),*)] { $($it:item)* } | |
12 | ) else * else { | |
13 | $($it2:item)* | |
14 | }) => { | |
15 | __cfg_if_items! { | |
16 | () ; | |
17 | $( ( ($($meta),*) ($($it)*) ), )* | |
18 | ( () ($($it2)*) ), | |
19 | } | |
20 | } | |
21 | } | |
22 | ||
23 | macro_rules! __cfg_if_items { | |
24 | (($($not:meta,)*) ; ) => {}; | |
25 | (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { | |
54a0048b | 26 | __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* } |
92a42be0 SL |
27 | __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } |
28 | } | |
29 | } | |
30 | ||
31 | macro_rules! __cfg_if_apply { | |
32 | ($m:meta, $($it:item)*) => { | |
33 | $(#[$m] $it)* | |
34 | } | |
35 | } | |
36 | ||
37 | macro_rules! s { | |
9cc50fc6 | 38 | ($($(#[$attr:meta])* pub struct $i:ident { $($field:tt)* })*) => ($( |
92a42be0 SL |
39 | __item! { |
40 | #[repr(C)] | |
9cc50fc6 | 41 | $(#[$attr])* |
92a42be0 SL |
42 | pub struct $i { $($field)* } |
43 | } | |
44 | impl ::dox::Copy for $i {} | |
45 | impl ::dox::Clone for $i { | |
46 | fn clone(&self) -> $i { *self } | |
47 | } | |
48 | )*) | |
49 | } | |
50 | ||
51 | macro_rules! f { | |
52 | ($(pub fn $i:ident($($arg:ident: $argty:ty),*) -> $ret:ty { | |
53 | $($body:stmt);* | |
54 | })*) => ($( | |
55 | #[inline] | |
56 | #[cfg(not(dox))] | |
57 | pub unsafe extern fn $i($($arg: $argty),*) -> $ret { | |
58 | $($body);* | |
59 | } | |
60 | ||
61 | #[cfg(dox)] | |
62 | #[allow(dead_code)] | |
63 | pub unsafe extern fn $i($($arg: $argty),*) -> $ret { | |
64 | loop {} | |
65 | } | |
66 | )*) | |
67 | } | |
68 | ||
69 | macro_rules! __item { | |
70 | ($i:item) => ($i) | |
71 | } | |
72 | ||
73 | #[cfg(test)] | |
74 | mod tests { | |
75 | cfg_if! { | |
76 | if #[cfg(test)] { | |
77 | use std::option::Option as Option2; | |
78 | fn works1() -> Option2<u32> { Some(1) } | |
79 | } else { | |
80 | fn works1() -> Option<u32> { None } | |
81 | } | |
82 | } | |
83 | ||
84 | cfg_if! { | |
85 | if #[cfg(foo)] { | |
86 | fn works2() -> bool { false } | |
87 | } else if #[cfg(test)] { | |
88 | fn works2() -> bool { true } | |
89 | } else { | |
90 | fn works2() -> bool { false } | |
91 | } | |
92 | } | |
93 | ||
94 | cfg_if! { | |
95 | if #[cfg(foo)] { | |
96 | fn works3() -> bool { false } | |
97 | } else { | |
98 | fn works3() -> bool { true } | |
99 | } | |
100 | } | |
101 | ||
102 | #[test] | |
103 | fn it_works() { | |
104 | assert!(works1().is_some()); | |
105 | assert!(works2()); | |
106 | assert!(works3()); | |
107 | } | |
108 | } |