1#[doc = crate::_tags!(code)]
7#[doc = crate::_doc_meta!{
9 location("code/util", macro is),
10}]
11#[macro_export]
84#[cfg_attr(cargo_primary_package, doc(hidden))]
85macro_rules! is· {
86 ($cond:expr, $then:expr) => {
88 $crate::is!(%if $cond, { $then }) };
89 ($cond:expr, $then:expr;) => {
90 $crate::is!(%if $cond,
91 { #[allow(clippy::diverging_sub_expression)] let _ = $then; }
92 )
93 };
94 ($cond:expr, $then:expr, $else:expr) => {
95 $crate::is!(%if $cond, { $then }, { $else }) };
96 ($cond:expr, $then:expr;, $else:expr) => {
97 $crate::is!(%if $cond,
98 { #[allow(clippy::diverging_sub_expression)] let _ = $then; },
99 { $else }
100 )
101 };
102 ($cond:expr, $then:expr, $else:expr;) => {
103 $crate::is!(%if $cond, { $then }, { $else; }) };
104 ($cond:expr, $then:expr;, $else:expr;) => {
105 $crate::is!(%if $cond,
106 { #[allow(clippy::diverging_sub_expression)] let _ = $then; },
107 { #[allow(clippy::diverging_sub_expression)] let _ = $else; }
108 )
109 };
110 ($cond:expr, $then:expr,) => {
111 $crate::is!(%if $cond, { $then }, {}) };
112 ($cond:expr, $then:expr; ,) => {
113 $crate::is!(%if $cond,
114 { #[allow(clippy::diverging_sub_expression)] let _ = $then; },
115 {}
116 )
117 };
118 ($cond:expr, , $else:expr) => {
119 $crate::is!(%if $cond, {}, { $else }) };
120 ($cond:expr, , $else:expr;) => {
121 $crate::is!(%if $cond,
122 {},
123 { #[allow(clippy::diverging_sub_expression)] let _ = $else; }
124 )
125 };
126
127 (let $pat:pat = $cond:expr, $then:expr) => {
129 $crate::is!(%let $pat = $cond, { $then }) };
130 (let $pat:pat = $cond:expr, $then:expr;) => {
131 $crate::is!(%let $pat = $cond,
132 { #[allow(clippy::diverging_sub_expression)] let _ = $then; }
133 )
134 };
135 (let $pat:pat = $cond:expr, $then:expr, $else:expr) => {
136 $crate::is!(%let $pat = $cond, { $then }, { $else }) };
137 (let $pat:pat = $cond:expr, $then:expr;, $else:expr) => {
138 $crate::is!(%let $pat = $cond,
139 { #[allow(clippy::diverging_sub_expression)] let _ = $then; },
140 { $else }
141 )
142 };
143 (let $pat:pat = $cond:expr, $then:expr, $else:expr;) => {
144 $crate::is!(%let $pat = $cond,
145 { $then },
146 { #[allow(clippy::diverging_sub_expression)] let _ = $else; }
147 )
148 };
149 (let $pat:pat = $cond:expr, $then:expr;, $else:expr;) => {
150 $crate::is!(%let $pat = $cond,
151 { #[allow(clippy::diverging_sub_expression)] let _ = $then; },
152 { #[allow(clippy::diverging_sub_expression)] let _ = $else; }
153 )
154 };
155 (let $pat:pat = $cond:expr, $then:expr,) => {
156 $crate::is!(%let $pat = $cond, { $then }, {}) };
157 (let $pat:pat = $cond:expr, $then:expr; ,) => {
158 $crate::is!(%let $pat = $cond,
159 { #[allow(clippy::diverging_sub_expression)] let _ = $then; },
160 {}
161 )
162 };
163 (let $pat:pat = $cond:expr, , $else:expr) => {
164 $crate::is!(%let $pat = $cond, {}, { $else }) };
165 (let $pat:pat = $cond:expr, , $else:expr;) => {
166 $crate::is!(%let $pat = $cond,
167 {},
168 { #[allow(clippy::diverging_sub_expression)] let _ = $else; }
169 )
170 };
171
172 (% if $cond:expr, $then:block) => {
174 #[allow(clippy::question_mark, reason = "to remain const-friendly")]
175 if $cond $then };
176 (% if $cond:expr, $then:block, $else:block) => {
177 if $cond $then else $else
178 };
179 (% let $pat:pat = $cond:expr, $then:block) => {
180 #[allow(clippy::question_mark, reason = "to remain const-friendly")]
181 if let $pat = $cond $then };
182 (% let $pat:pat = $cond:expr, $then:block, $else:block) => {
183 if let $pat = $cond $then else $else
184 };
185}
186#[doc(inline)]
187pub use is· as is;
188
189#[cfg(test)]
190mod _test {
191 use super::is;
192
193 #[test]
194 fn is_if_expr() {
195 assert_eq!('a', is![true, 'a', 'b']);
196 assert_eq!('b', is![false, 'a', 'b']);
197 }
198 #[test]
199 fn is_if_statement_then() {
200 let mut n = 0;
201 is![true, n += 1;];
202 is![false, n += 10;];
203 assert_eq!(1, n);
204 }
205 #[test]
206 fn is_if_statement_branches() {
207 let mut n = 0;
208 is![true, n += 1;, n += 10;];
209 assert_eq!(1, n);
210 is![false, n += 1;, n += 10;];
211 assert_eq!(11, n);
212 }
213 #[test]
214 fn is_if_empty_else() {
215 let mut n = 0;
216 is![true, n += 1;,];
217 is![false, n += 10;,];
218 assert_eq!(1, n);
219 }
220 #[test]
221 fn is_if_empty_then() {
222 let mut n = 0;
223 is![true, , n += 10;];
224 is![false, , n += 1;];
225 assert_eq!(1, n);
226 }
227 #[test]
228 fn is_if_empty_then_diverges() {
229 fn check(ok: bool) -> Result<(), &'static str> {
230 is![ok, , return Err("not ok");];
231 Ok(())
232 }
233 assert_eq!(Ok(()), check(true));
234 assert_eq!(Err("not ok"), check(false));
235 }
236 #[test]
237 fn is_let_expr() {
238 let somea = Some('a');
239 let noa: Option<char> = None;
240 assert_eq!('a', is![let Some(a) = somea, a, 'b']);
241 assert_eq!('b', is![let Some(a) = noa, a, 'b']);
242 }
243 #[test]
244 fn is_let_statement_then() {
245 let mut n = 0;
246 is![let Some(v) = Some(2), n += v;];
247 is![let Some(v) = None::<i32>, n += v;];
248 assert_eq!(2, n);
249 }
250 #[test]
251 fn is_let_statement_branches() {
252 let mut n = 0;
253 is![let Some(v) = Some(2), n += v;, n += 10;];
254 assert_eq!(2, n);
255 is![let Some(v) = None::<i32>, n += v;, n += 10;];
256 assert_eq!(12, n);
257 }
258 #[test]
259 fn is_let_empty_else() {
260 let mut n = 0;
261 is![let Some(v) = Some(3), n += v;,];
262 is![let Some(v) = None::<i32>, n += v;,];
263 assert_eq!(3, n);
264 }
265 #[test]
266 fn is_let_empty_then() {
267 let mut n = 0;
268 is![let Some(_) = Some(1), , n += 10;];
269 is![let Some(_) = None::<i32>, , n += 1;];
270 assert_eq!(1, n);
271 }
272 #[test]
273 fn is_nested_statement() {
274 let mut n = 2;
275 let is_true = Some(true);
276 is![let Some(b) = is_true, is![b, n += 3;]];
277 assert_eq!(5, n);
278 }
279}