blob: bb5d9eeadd182cb8dea02f07c7b11f5aa66424e3 [file] [log] [blame]
Alex Crichton5d6cf052015-09-11 14:52:34 -07001/// 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.
Alex Crichton31504842015-09-10 23:43:41 -07009macro_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
Alex Crichton31504842015-09-10 23:43:41 -070023macro_rules! __cfg_if_items {
24 (($($not:meta,)*) ; ) => {};
25 (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
26 __cfg_if_apply! { cfg(all($($m,)* not(any($($not),*)))), $($it)* }
27 __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
28 }
29}
30
Alex Crichton31504842015-09-10 23:43:41 -070031macro_rules! __cfg_if_apply {
32 ($m:meta, $($it:item)*) => {
33 $(#[$m] $it)*
34 }
35}
36
Alex Crichton5d6cf052015-09-11 14:52:34 -070037macro_rules! s {
38 ($(pub struct $i:ident { $($field:tt)* })*) => ($(
39 __item! {
40 #[repr(C)]
41 pub struct $i { $($field)* }
42 }
Alex Crichton24abc4f2015-09-16 23:54:56 -070043 impl ::dox::Copy for $i {}
44 impl ::dox::Clone for $i {
Alex Crichton5d6cf052015-09-11 14:52:34 -070045 fn clone(&self) -> $i { *self }
46 }
47 )*)
48}
49
50macro_rules! __item {
51 ($i:item) => ($i)
52}
53
Alex Crichton31504842015-09-10 23:43:41 -070054#[cfg(test)]
55mod tests {
56 cfg_if! {
57 if #[cfg(test)] {
58 use std::option::Option as Option2;
59 fn works1() -> Option2<u32> { Some(1) }
60 } else {
61 fn works1() -> Option<u32> { None }
62 }
63 }
64
65 cfg_if! {
66 if #[cfg(foo)] {
67 fn works2() -> bool { false }
68 } else if #[cfg(test)] {
69 fn works2() -> bool { true }
70 } else {
71 fn works2() -> bool { false }
72 }
73 }
74
75 cfg_if! {
76 if #[cfg(foo)] {
77 fn works3() -> bool { false }
78 } else {
79 fn works3() -> bool { true }
80 }
81 }
82
83 #[test]
84 fn it_works() {
85 assert!(works1().is_some());
86 assert!(works2());
87 assert!(works3());
88 }
89}