devela/code/util/iif.rs
1// devela::code::util::iif
2//
3//! inline if macro.
4//
5
6/// *`i`nline `if`* macro.
7///
8/// A inline alternative for `if` and `if let`.
9///
10/// # Examples
11///
12/// Replacing `if`:
13/// ```
14/// # use devela::iif;
15/// // This
16/// let s = iif![1 > 0; true; false];
17///
18/// // Would be equivalent to
19/// let s = if 1 > 0 {
20/// true
21/// } else {
22/// false
23/// };
24/// ```
25///
26/// Replacing `if let`:
27/// ```
28/// # use devela::iif;
29/// let num = Some(123);
30///
31/// // This
32/// iif![let Some(n) = num ; println!("num:{n}") ; { dbg![num]; }];
33///
34/// // Would be equivalent to
35/// if let Some(n) = num {
36/// println!("num:{n}")
37/// } else {
38/// dbg![num];
39/// }
40/// ```
41///
42/// Nested:
43/// ```
44/// # use devela::iif;
45/// let mut s = String::new();
46/// let is_premium = Some(true);
47///
48/// // This
49/// iif![let Some(b) = is_premium; iif![b; s += " [premium]"]];
50///
51/// // Would be equivalent to
52/// if let Some(b) = is_premium {
53/// if b {
54/// s += " [premium]";
55/// }
56/// }
57/// ```
58#[macro_export]
59#[cfg_attr(cargo_primary_package, doc(hidden))]
60macro_rules! iif {
61 ($if:expr; $true:expr) => {
62 if $if {
63 $true
64 }
65 };
66 ($if:expr ; $true:expr ; $($false:expr)?) => {
67 // WAIT: [stmt_expr_attributes](https://github.com/rust-lang/rust/issues/15701)
68 // #[allow(clippy::redundant_else)]
69 if $if {
70 $true
71 } else {
72 $( $false )?
73 }
74 };
75
76 (let $pat:pat = $if:expr ; $true:expr) => {
77 #[allow(clippy::question_mark)]
78 if let $pat = $if {
79 $true
80 }
81 };
82 (let $pat:pat = $if:expr ; $true:expr ; $($false:expr)? ) => {
83 if let $pat = $if {
84 $true
85 } else {
86 $( $false )?
87 }
88 };
89}
90#[doc(inline)]
91pub use iif;
92
93#[cfg(test)]
94mod test_iif {
95 use crate::iif;
96
97 #[test]
98 fn iif() {
99 assert_eq!('a', iif!(true ; 'a' ; 'b'));
100 assert_eq!('b', iif!(false ; 'a' ; 'b'));
101 }
102
103 #[test]
104 fn iif_let() {
105 let somea = Some('a');
106 let noa: Option<char> = None;
107
108 assert_eq!('a', iif!(let Some(a) = somea; a ; 'b'));
109 assert_eq!('b', iif!(let Some(a) = noa; a ; 'b'));
110 }
111}