devela/code/util/
cfg_if.rs
1#[doc = crate::doc_!(vendor: "cfg-if")]
36#[macro_export]
37#[cfg_attr(cargo_primary_package, doc(hidden))]
38macro_rules! cfg_if {
39 ( $( if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* } ) else+
41 else { $( $e_tokens:tt )* }
42 ) => {
43 $crate::cfg_if! {
44 @__items () ;
45 $( (( $i_meta ) ( $( $i_tokens )* )) , )+
46 (() ( $( $e_tokens )* )) ,
47 }
48 };
49 ( $( if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* } ) else+
51 else { $( $e_tokens:tt )* }
52 if $($extra_conditions:tt)+
53 ) => {
54 $crate::cfg_if! {
55 @__items () ;
56 $( (( $i_meta ) ( $( $i_tokens )* )) , )+
57 (() ( $( $e_tokens )* )) ,
58 }
59 $crate::cfg_if! { if $($extra_conditions)+ }
60 };
61
62 ( if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
64 $( else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* } )*
65 ) => {
66 $crate::cfg_if! {
67 @__items () ;
68 (( $i_meta ) ( $( $i_tokens )* )) ,
69 $( (( $e_meta ) ( $( $e_tokens )* )) , )*
70 }
71 };
72 ( if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
74 $( else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* } )*
75 if $($extra_conditions:tt)+
76 ) => {
77 $crate::cfg_if! {
78 @__items () ;
79 (( $i_meta ) ( $( $i_tokens )* )) ,
80 $( (( $e_meta ) ( $( $e_tokens )* )) , )*
81 }
82 $crate::cfg_if! { if $($extra_conditions)+ }
83 };
84
85 (@__items ( $( $_:meta , )* ) ; ) => {};
90 ( @__items ( $( $no:meta , )* ) ;
91 (( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
92 $( $rest:tt , )*
93 ) => {
94 #[cfg(all(
98 $( $yes , )?
99 not(any( $( $no ),* ))
100 ))]
101 $crate::cfg_if! { @__identity $( $tokens )* }
102
103 $crate::cfg_if! {
107 @__items ( $( $no , )* $( $yes , )? ) ;
108 $( $rest , )*
109 }
110 };
111
112 (@__identity $( $tokens:tt )* ) => {
115 $( $tokens )*
116 };
117}
118#[doc(inline)]
119pub use cfg_if;
120
121#[cfg(test)]
122mod test_cfg_if {
123 #![allow(dead_code, unexpected_cfgs)]
124
125 use crate::cfg_if;
126
127 cfg_if! {
128 if #[cfg(test)] {
129 use core::option::Option as Option2;
130 fn works1() -> Option2<u32> { Some(1) }
131 } else {
132 fn works1() -> Option<u32> { None }
133 }
134 }
135
136 cfg_if! {
137 if #[cfg(foo)] {
138 fn works2() -> bool { false }
139 } else if #[cfg(test)] {
140 fn works2() -> bool { true }
141 } else {
142 fn works2() -> bool { false }
143 }
144 }
145
146 cfg_if! {
147 if #[cfg(foo)] {
148 fn works3() -> bool { false }
149 } else {
150 fn works3() -> bool { true }
151 }
152 }
153
154 cfg_if! {
155 if #[cfg(test)] {
156 use core::option::Option as Option3;
157 fn works4() -> Option3<u32> { Some(1) }
158 }
159 }
160
161 cfg_if! {
162 if #[cfg(foo)] {
163 fn works5() -> bool { false }
164 } else if #[cfg(test)] {
165 fn works5() -> bool { true }
166 }
167 }
168
169 cfg_if! {
171 if #[cfg(foo)] {
172 fn works6() -> bool { false }
173 } else if #[cfg(test)] {
174 fn works6() -> bool { true }
175 }
176 if #[cfg(test)] {
177 fn works7() -> bool { true }
178 } else {
179 fn works7() -> bool { false }
180 }
181 }
182 cfg_if! {
183 if #[cfg(test)] {
184 fn works8() -> bool { true }
185 } else if #[cfg(foo)] {
186 fn works8() -> bool { false }
187 }
188 if #[cfg(foo)] {
189 fn works9() -> bool { false }
190 } else if #[cfg(test)] {
191 fn works9() -> bool { true }
192 }
193 }
194
195 #[test]
196 fn it_works() {
197 assert!(works1().is_some());
198 assert!(works2());
199 assert!(works3());
200 assert!(works4().is_some());
201 assert!(works5());
202 }
203
204 #[test]
205 #[allow(clippy::assertions_on_constants)]
206 fn test_usage_within_a_function() {
207 cfg_if! {if #[cfg(debug_assertions)] {
208 assert!(cfg!(debug_assertions));
211 assert_eq!(4, 2+2);
212 } else {
213 assert!(works1().is_some());
214 assert_eq!(10, 5+5);
215 }}
216 }
217
218 #[allow(dead_code)]
219 trait Trait {
220 fn blah(&self);
221 }
222
223 #[allow(dead_code)]
224 struct Struct;
225
226 impl Trait for Struct {
227 cfg_if! {
228 if #[cfg(feature = "blah")] {
229 fn blah(&self) {
230 unimplemented!();
231 }
232 } else {
233 fn blah(&self) {
234 unimplemented!();
235 }
236 }
237 }
238 }
239}