Implementing a switch-like statement with macros
⚓ Rust 📅 2025-10-24 👤 surdeus 👁️ 3hi there,
I am still learning Rust and as a self-assigned exercize to better understand macros, I am trying to implement a switch-like statement with macros.
Basically, I'd like to replicate the switch from Go, and translate this:
fn foo(cut: f64) {
let v = 42.0;
switch! {
v > cut => println!("passing cut"),
v < -cut => println!("case 2"),
v == cut/2.0 => println!("special case 3"),
v == 42.0 => println!("answer to the universe"),
_ => println!("default case"),
}
}
to a chain of if-else-ifs:
fn foo(cut: f64) {
let v = 42.0;
if v > cut {
println!("passing cut");
} else if v < -cut {
println!("case 2");
} else if v == cut / 2.0 {
println!("special case 3");
} else if v == 42.0 {
println!("answer to the universe");
} else {
println!("default case");
}
}
as a first stab, I tried this:
macro_rules! switch {
($($a:expr => $b:expr $(,)?)*) => {
$(if $a {
return $b;
})*
};
(_ => $e:expr $(,)?) => {
$(if true {
return $e;
})*
};
}
but of course that doesn't work (I guess I am not using the correct pattern matcher to match for _):
error: in expressions, `_` can only be used on the left-hand side of an assignment
--> main.rs:88:9
|
88 | _ => println!("default case"),
| ^ `_` not allowed here
I then tried:
macro_rules! switch {
($($a:expr => $b:expr,)* _ => $e:expr $(,)?) => {
$(if $a {
return $b;
})*
if true {
return $e;
}
};
}
and got:
error: local ambiguity when calling macro `switch`: multiple parsing options: built-in NTs expr ('a') or 1 other option.
--> main.rs:88:9
|
88 | _ => println!("default case"),
| ^
→ I guess macro_rules doesn't cut it for what I'd like to achieve and I would need to resort to TokenStreams ?
(we need to keep some state to remember whether we are considering the first switch-case, the last/default one or any other case. And it seems to macro_rules doesn't provide this kind of information).
→ but perhaps the more fundamental question is: can this (a switch-like statement) be achieved at all ?
thanks for your time and input.
-s
4 posts - 4 participants
🏷️ Rust_feed