mac/
cfg.rs

1//! Macros for conditional compilation.
2
3/// Compile-time matching on config variables.
4///
5/// Only the branch relevant on your machine will be type-checked!
6///
7/// # Example
8///
9/// ```
10/// # #[macro_use] extern crate mac;
11/// # fn main() {
12/// let mascot = match_cfg! {
13///     (target_os = "linux") => "penguin",
14///     (target_os = "openbsd") => "blowfish",
15///     _ => "unknown",
16/// };
17/// println!("{}", mascot);
18/// # }
19/// ```
20///
21#[macro_export]
22macro_rules! match_cfg {
23    ( $( ($cfg:meta) => $e:expr, )* _ => $last:expr, ) => {
24        match () {
25            $(
26                #[cfg($cfg)]
27                () => $e,
28            )*
29
30            #[cfg(all( $( not($cfg) ),* ))]
31            () => $last,
32        }
33    };
34
35    ( $( ($cfg:meta) => $e:expr, )* ) => {
36        match_cfg! {
37            $(
38                ($cfg) => $e,
39            )*
40
41            _ => {
42                #[allow(dead_code)]
43                #[static_assert]
44                static MATCH_CFG_FALLBACK_UNREACHABLE: bool = false;
45            }
46        }
47    };
48}
49
50/// Compile-time conditional expression.
51///
52/// # Example
53///
54/// ```
55/// # #[macro_use] extern crate mac;
56/// # fn main() {
57/// if_cfg!(test {
58///     println!("Crate built as a test suite");
59/// })
60/// # }
61/// ```
62///
63/// Unlike `if cfg!(...)`, this will not even compile the unused branch.
64///
65/// ```
66/// # #[macro_use] extern crate mac;
67/// # fn main() {
68/// let x = if_cfg!(any(bleh, blah="bluh") {
69///     some_undefined_function_name();
70///     2 + "doesn't even typecheck"
71/// } else {
72///     3
73/// });
74///
75/// assert_eq!(x, 3);
76/// # }
77/// ```
78#[macro_export]
79macro_rules! if_cfg {
80    ($cfg:meta $t:block else $f:block) => {
81        match_cfg! {
82            ($cfg) => $t,
83            _ => $f,
84        }
85    };
86
87    ($cfg:meta $t:block) => {
88        if_cfg!($cfg $t else { })
89    };
90}