#![cfg_attr(not(test), no_std)]
#[macro_export(local_inner_macros)]
macro_rules! if_chain {
($($tt:tt)*) => {
__if_chain! { @init () $($tt)* }
};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __if_chain {
(@init ($($tt:tt)*) then $then:block else $other:block) => {
__if_chain! { @expand $other $($tt)* then $then }
};
(@init ($($tt:tt)*) then $then:block) => {
__if_chain! { @expand {} $($tt)* then $then }
};
(@init ($($tt:tt)*) $head:tt $($tail:tt)*) => {
__if_chain! { @init ($($tt)* $head) $($tail)* }
};
(@expand $other:block let $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
match $expr {
$($pat)|+ => __if_chain! { @expand $other $($tt)+ }
}
};
(@expand $other:block if let $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
match $expr {
$($pat)|+ => __if_chain! { @expand $other $($tt)+ },
_ => $other
}
};
(@expand {} if $expr:expr; $($tt:tt)+) => {
if $expr {
__if_chain! { @expand {} $($tt)+ }
}
};
(@expand $other:block if $expr:expr; $($tt:tt)+) => {
if $expr {
__if_chain! { @expand $other $($tt)+ }
} else {
$other
}
};
(@expand $other:block then $then:block) => {
$then
};
}
#[cfg(test)]
mod tests {
#[test]
fn simple() {
let x: Option<Result<Option<String>, (u32, u32)>> = Some(Err((41, 42)));
let mut success = false;
if_chain! {
if let Some(y) = x;
if let Err(z) = y;
let (_, b) = z;
if b == 42;
then { success = true; }
}
assert!(success);
}
#[test]
fn empty() {
let success;
if_chain! {
then { success = true; }
}
assert!(success);
}
#[test]
fn empty_with_else() {
let success;
if_chain! {
then { success = true; }
else { unreachable!(); }
}
assert!(success);
}
#[test]
fn if_let_multiple_patterns() {
#[derive(Copy, Clone)]
enum Robot { Nano, Biscuit1, Biscuit2 }
for &(robot, expected) in &[
(Robot::Nano, false),
(Robot::Biscuit1, true),
(Robot::Biscuit2, true),
] {
let is_biscuit = if_chain! {
if let Robot::Biscuit1 | Robot::Biscuit2 = robot;
then { true } else { false }
};
assert_eq!(is_biscuit, expected);
}
}
#[test]
fn let_multiple_patterns() {
let x: Result<u32, u32> = Ok(42);
if_chain! {
let Ok(x) | Err(x) = x;
then { assert_eq!(x, 42); }
else { panic!(); }
}
}
}