# Create when statment with macros

Hi everybody. I wonder if there is some possibility to create a macro that simplify the if/else if branches like the when statement in Kotlin (https://kotlinlang.org/docs/reference/control-flow.html).

Something like:

``````let x = 0;
let positive = when! {
x >= 0 => true,
x < 0 => false
};
``````

The purpose is to simplify complex if/else if branches like:

``````when! {
coord.v < 250 => 0,
coord.h <= leftLimit.h && hSpeed <= 20 => -10,
coord.h >= rightLimit.h && hSpeed >= -20 => 10,
hSpeed < -40 => -60,
hSpeed > 40 => 60,
coord.h >= leftLimit.h + 5 && coord.h <= rightLimit.h - 5) => {
when! {
hSpeed < -30 => -60,
hSpeed > 30 => 60,
hSpeed < 0 => -10,
hSpeed > 0 => 10,
else => 0
}
},
else => 0
}
``````

Thank’s

Doesn’t the `match { ... if ... }` syntax satisfy your needs? Your first example would be as such:

``````let x = 0;
let positive = match x {
_ if x >= 0 => true,
_ if x < 0 => false,
// the last part is essentially the "else" case
_ => panic!("Something really weird happened")
};
``````

Second example would be more complicated, of course, but also very close to your one.

2 Likes

Range patterns and match guards cover a lot of use cases. See here for more information.

1 Like

Thank you for both responses I didn’t see the part of the documentation.

Here’s an ok version: https://play.rust-lang.org/?gist=e462d19f41d5215a07fa17af94a65316

``````macro_rules! when {
( \$(\$e:expr => \$v:expr,)* else \$w:expr ) => {
match () {
\$(() if \$e => \$v,)*
_ => \$w,
}
}
}

fn main() {
let x = 0;
let signum = when! {
x > 0 => 1,
x < 0 => -1,
else 0
};
println!("{:?}", signum);
}
``````

But definitely prefer patterns and guards where convenient.

1 Like