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)*) => { 26 __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* } 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 { 38 ($($(#[$attr:meta])* pub struct $i:ident { $($field:tt)* })*) => ($( 39 __item! { 40 #[repr(C)] 41 $(#[$attr])* 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 } 109