/// A macro for defining #[cfg] if-else statements. /// /// This is similar to the `if/elif` C preprocessor macro by allowing definition /// of a cascade of `#[cfg]` cases, emitting the implementation which matches /// first. /// /// This allows you to conveniently provide a long list #[cfg]'d blocks of code /// without having to rewrite each clause multiple times. macro_rules! cfg_if { ($( if #[cfg($($meta:meta),*)] { $($it:item)* } ) else * else { $($it2:item)* }) => { __cfg_if_items! { () ; $( ( ($($meta),*) ($($it)*) ), )* ( () ($($it2)*) ), } } } macro_rules! __cfg_if_items { (($($not:meta,)*) ; ) => {}; (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { __cfg_if_apply! { cfg(all($($m,)* not(any($($not),*)))), $($it)* } __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } } } macro_rules! __cfg_if_apply { ($m:meta, $($it:item)*) => { $(#[$m] $it)* } } macro_rules! s { ($(pub struct $i:ident { $($field:tt)* })*) => ($( __item! { #[repr(C)] pub struct $i { $($field)* } } impl ::dox::Copy for $i {} impl ::dox::Clone for $i { fn clone(&self) -> $i { *self } } )*) } macro_rules! f { ($(pub fn $i:ident($($arg:ident: $argty:ty),*) -> $ret:ty { $($body:stmt);* })*) => ($( #[inline] #[cfg(not(dox))] pub unsafe extern fn $i($($arg: $argty),*) -> $ret { $($body);* } #[cfg(dox)] #[allow(dead_code)] pub unsafe extern fn $i($($arg: $argty),*) -> $ret { loop {} } )*) } macro_rules! __item { ($i:item) => ($i) } #[cfg(test)] mod tests { cfg_if! { if #[cfg(test)] { use std::option::Option as Option2; fn works1() -> Option2 { Some(1) } } else { fn works1() -> Option { None } } } cfg_if! { if #[cfg(foo)] { fn works2() -> bool { false } } else if #[cfg(test)] { fn works2() -> bool { true } } else { fn works2() -> bool { false } } } cfg_if! { if #[cfg(foo)] { fn works3() -> bool { false } } else { fn works3() -> bool { true } } } #[test] fn it_works() { assert!(works1().is_some()); assert!(works2()); assert!(works3()); } }