Created
December 29, 2014 19:25
-
-
Save Mr-Byte/5257de73660630d236d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(macro_rules)] | |
macro_rules! active_match { | |
//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, | |
None => 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, | |
None => 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, | |
None => active_match! { $m, $($i_rest($($ps_rest),*) => $b_rest),+ } | |
} | |
}; | |
//Single zero parameter case | |
($m:expr, $i:ident() => $b:block) => { | |
match $i($m) { | |
Some(()) => $b, | |
None => panic!("Encountered an unmatched active case.") | |
} | |
}; | |
//Single one parameter case | |
($m:expr, $i:ident($p:pat) => $b:block) => { | |
match $i($m) { | |
Some($p) => $b, | |
None => panic!("Encountered an unmatched active case.") | |
} | |
}; | |
//Single multiple parameter case | |
($m:expr, $i:ident($($ps:pat),*) => $b:block) => { | |
match $i($m) { | |
Some(($($ps),*)) => $b, | |
None => panic!("Encountered an unmatched active case.") | |
} | |
}; | |
//Zero parameter case followed by a wildcard. | |
($m:expr, $i:ident() => $b:block, _ => $b_rest_default:block) => { | |
match $i($m) { | |
Some(()) => $b, | |
None => $b_rest_default | |
} | |
}; | |
//One parameter case followed by a wildcard. | |
($m:expr, $i:ident($p:pat) => $b:block, _ => $b_rest_default:block) => { | |
match $i($m) { | |
Some($p) => $b, | |
None => $b_rest_default | |
} | |
}; | |
//Multiple parameter case followed by a wildcard. | |
($m:expr, $i:ident($($ps:pat),*) => $b:block, _ => $b_rest_default:block) => { | |
match $i($m) { | |
Some(($($ps),*)) => $b, | |
None => $b_rest_default | |
} | |
}; | |
//Zero parameter case followed by one or more cases and a wildcard. | |
($m:expr, $i:ident() => $b:block $(, $i_rest:ident($($ps_rest:pat),*) => $b_rest:block)+, _ => $b_rest_default:$block) => { | |
match $i($m) { | |
Some(()) => $b, | |
None => active_match! { $m, $($i_rest($($ps_rest),*) => $b_rest),+, _ => $b_rest_default } | |
} | |
}; | |
//One parameter case followed by one or more cases and a wildcard. | |
($m:expr, $i:ident($p:pat) => $b:block $(, $i_rest:ident($($ps_rest:pat),*) => $b_rest:block)+, _ => $b_rest_default:$block) => { | |
match $i($m) { | |
Some($p) => $b, | |
None => active_match! { $m, $($i_rest($($ps_rest),*) => $b_rest),*+ _ => $b_rest_default } | |
} | |
}; | |
//Multiple parameter case followed by one or more cases and a wildcard. | |
($m:expr, $i:ident($($ps:pat),*) => $b:block $(, $i_rest:ident($($ps_rest:pat),*) => $b_rest:block)+, _ => $b_rest_default:$block) => { | |
match $i($m) { | |
Some(($($ps),*)) => $b, | |
None => active_match! { $m, $($i_rest($($ps_rest),*) => $b_rest),+, _ => $b_rest_default } | |
} | |
}; | |
//Single wild card case | |
($m:expr, _ => $b:block) => { | |
$b | |
}; | |
} | |
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 | |
} | |
} | |
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) }, | |
_ => { 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) }, | |
_ => { 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 {}, and tripled is {}.", n2, n3) }, | |
double_and_triple_if_even(n2, n3) => { println!("{} doubled is {}, and tripled is {}.", i, n2, n3) }, | |
_ => { println!("{} is odd.", i); } | |
} | |
} | |
println!("----"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment