Skip to content

Instantly share code, notes, and snippets.

@munael
Forked from Mr-Byte/active_match.rs
Last active September 6, 2015 20:31
Show Gist options
  • Save munael/5915d083069b3411ade6 to your computer and use it in GitHub Desktop.
Save munael/5915d083069b3411ade6 to your computer and use it in GitHub Desktop.
#![feature(macro_rules)]
macro_rules! active_match {
//Single zero parameter case
($m:expr, $i:ident() => $b:block) => {
match $i($m) {
Some(()) => $b,
_ => panic!("Encountered an unmatched active case.")
}
};
//Single one parameter case
($m:expr, $i:ident($p:pat) => $b:block) => {
match $i($m) {
Some($p) => $b,
_ => panic!("Encountered an unmatched active case.")
}
};
//Single multiple parameter case
($m:expr, $i:ident($($ps:pat),*) => $b:block) => {
match $i($m) {
Some(($($ps),*)) => $b,
_ => panic!("Encountered an unmatched active case.")
}
};
//Zero parameter case followed by one or more cases
($m:expr, $i:ident() => $b:block $(, $i_rest:ident($($ps_rest:pat),*) => $b_rest:block)+) => {
match $i($m) {
Some(()) => $b,
_ => active_match! { $m, $($i_rest($($ps_rest),*) => $b_rest),+ }
}
};
//One parameter case followed by one or more cases
($m:expr, $i:ident($p:pat) => $b:block $(, $i_rest:ident($($ps_rest:pat),*) => $b_rest:block)+) => {
match $i($m) {
Some($p) => $b,
_ => active_match! { $m, $($i_rest($($ps_rest),*) => $b_rest),+ }
}
};
//Multiple parameter case followed by one or more cases
($m:expr, $i:ident($($ps:pat),*) => $b:block $(, $i_rest:ident($($ps_rest:pat),*) => $b_rest:block)+) => {
match $i($m) {
Some(($($ps),*)) => $b,
_ => active_match! { $m, $($i_rest($($ps_rest),*) => $b_rest),+ }
}
};
}
fn is_even(n: i32) -> Option<()> {
if n % 2 == 0 { Some(()) } else { None }
}
fn is_odd(n: i32) -> Option<()> {
if n % 2 == 1 { Some(()) } else { None }
}
fn double_up(n:i32) -> Option<i32> {
Some(n*2)
}
fn double_and_triple_if_even(n: i32) -> Option<(i32, i32)> {
if n % 2 == 0 {
Some((n*2, n*3))
} else {
None
}
}
//Fake wildcard
fn otherwise<T>(_: T) -> Option<()> {
Some(())
}
fn main() {
println!("Testing two cases with no parameters.");
for i in range(1,10) {
active_match! { i,
is_even() => { println!("{} is an even number.", i) },
is_odd() => { println!("{} is an odd number.", i) }
}
}
println!("----");
println!("Testing one case with no parameters and a wildcard.");
for i in range(1,10) {
active_match! { i,
is_even() => { println!("{} is an even number.", i) },
otherwise() => { println!("{} is an odd number.", i) }
}
}
println!("----");
println!("Testing one case with one parameter.");
for i in range(1,10) {
active_match! { i,
double_up(n) => { println!("{} doubled is {}.", i, n) }
}
}
println!("----");
println!("Testing one case with two parameters and a wildcard.");
for i in range(1,10) {
active_match! { i,
double_and_triple_if_even(n2, n3) => { println!("{} doubled is {}, and tripled is {}.", i, n2, n3) },
otherwise() => { println!("{} is odd.", i); }
}
}
println!("----");
println!("Testing one case with two parameters, one case with a pattern and a parameter, and a wildcard.");
for i in range(1,10) {
active_match! { i,
double_and_triple_if_even(4, n3) => { println!("Two doubled is 4, and tripled is {}.", n3) },
double_and_triple_if_even(n2, n3) => { println!("{} doubled is {}, and tripled is {}.", i, n2, n3) },
otherwise() => { println!("{} is odd.", i); }
}
}
println!("----");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment