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}
91