cfg_exif/
expr.rs

1//! Conditional compilation at expression positions.
2
3pub use crate::{expr_cfg as cfg, expr_feature as feature};
4
5/// Compiles expressions conditionally on features.
6///
7/// # Examples
8///
9/// ```rust
10/// use cfg_exif::expr::feature;
11///
12/// assert_eq!(
13///     feature!(if ("foo") {
14///         0
15///     } else if (!"bar") {
16///         42
17///     } else {
18///         1
19///     }),
20///     42
21/// );
22/// ```
23#[macro_export]
24macro_rules! expr_feature {
25    (if ($name:literal) { $then1:expr } else $(if $condition:tt { $then2:expr } else)* { $else:expr }) => {
26        {
27            #[cfg(feature = $name)]
28            { $then1 }
29            #[cfg(not(feature = $name))]
30            { $crate::expr_feature!($(if $condition { $then2 } else)* { $else }) }
31        }
32    };
33    (if (!$name:literal) { $then1:expr } else $(if $condition:tt { $then2:expr } else)* { $else:expr }) => {
34        {
35            #[cfg(not(feature = $name))]
36            { $then1 }
37            #[cfg(feature = $name)]
38            { $crate::expr_feature!($(if $condition { $then2 } else)* { $else }) }
39        }
40    };
41    ({ $else:expr }) => {{
42        {
43            $else
44        }
45    }};
46}
47
48/// Compiles expressions conditionally on compile configurations.
49///
50/// # Examples
51///
52/// ```rust
53/// use cfg_exif::expr::cfg;
54///
55/// assert_eq!(
56///     cfg!(if (feature == "foo") {
57///         0
58///     } else if (target_pointer_width != "64") {
59///         1
60///     } else if ((target_family == "unix") && (feature == "bar")) {
61///         2
62///     } else if ((feature == "baz") || (target_os == "freebsd")) {
63///         3
64///     } else if (!(panic == "unwind")) {
65///         4
66///     } else {
67///         42
68///     }),
69///     42
70/// );
71/// ```
72#[macro_export]
73macro_rules! expr_cfg {
74    (if ($key:ident == $value:literal) { $then1:expr } else $(if $condition:tt { $then2:expr } else)* { $else:expr }) => {{
75        #[cfg($key = $value)]
76        {
77            $then1
78        }
79        #[cfg(not($key = $value))]
80        {
81            $crate::expr_cfg!($(if $condition { $then2 } else)* { $else })
82        }
83    }};
84    (if ($key:ident != $value:literal) { $then1:expr } else $(if $condition:tt { $then2:expr } else)* { $else:expr }) => {{
85        #[cfg(not($key = $value))]
86        {
87            $then1
88        }
89        #[cfg($key = $value)]
90        {
91            $crate::expr_cfg!($(if $condition { $then2 } else)* { $else })
92        }
93    }};
94    (if ($left:tt && $right:tt) { $then1:expr } else $(if $condition:tt { $then2:expr } else)* { $else:expr }) => {{
95        $crate::expr_cfg!(if $left {
96            $crate::expr_cfg!(if $right {
97                $then1
98            } else {
99                $crate::expr_cfg!($(if $condition { $then2 } else)* { $else })
100            })
101        } else {
102            $crate::expr_cfg!($(if $condition { $then2 } else)* { $else })
103        })
104    }};
105    (if ($left:tt || $right:tt) { $then1:expr } else $(if $condition:tt { $then2:expr } else)* { $else:expr }) => {{
106        $crate::expr_cfg!(if $left {
107            $then1
108        } else if $right {
109            $then1
110        } else {
111            $crate::expr_cfg!($(if $condition { $then2 } else)* { $else })
112        })
113    }};
114    (if (!$condition1:tt) { $then1:expr } else $(if $condition2:tt { $then2:expr } else)* { $else:expr }) => {{
115        $crate::expr_cfg!(if $condition1 {
116            $crate::expr_cfg!($(if $condition2 { $then2 } else)* { $else })
117        } else {
118            $then1
119        })
120    }};
121    ({ $else:expr }) => {{
122        {
123            $else
124        }
125    }};
126}