Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- macro_rules! expand_patterns {
- // if we're out of patterns, call `f` with the iterator we've constructed
- (CONTINUE: ($iter:ident => $use_iter:ident)) => {
- break $use_iter($iter);
- };
- (
- // distinguishes this case from the entry case
- CONTINUE:
- // we have to define the identifier used for the iterator because of hygiene
- // defining the identifier of the function is just for reusability
- ($iter:ident => $use_iter:ident)
- // expressions cannot be followed by blocks in macros
- if let $pat:pat = ($expr:expr) $new_iter:block $($rest:tt)*
- ) => {
- if let $pat = $expr {
- let $iter = $new_iter;
- // we recurse with the remaining patterns in both cases
- expand_patterns!(CONTINUE: ($iter => $use_iter) $($rest)*);
- } else {
- expand_patterns!(CONTINUE: ($iter => $use_iter) $($rest)*);
- }
- };
- // entry case
- (($iter:ident => $use_iter:ident) $($args:tt)*) => {
- // we expand inside a loop so we can use `break` as flow control
- loop {
- expand_patterns!(CONTINUE: ($iter => $use_iter) $($args)*);
- }
- }
- }
- fn use_iter(iter: impl Iterator<Item = (u64, bool)>) {
- for (t, v) in iter {
- println!("{}: {:?}", t, v);
- }
- }
- fn main() {
- let start_time = Some(0);
- let end_time = Some(100);
- let photon_count = Some(100);
- let iter = (0 .. 100).map(|t| (t, t & 1 != 0));
- let res = expand_patterns! {
- (iter => use_iter)
- if let Some(start_time) = (start_time) {
- iter.skip_while(|&(t, _)| t < start_time)
- }
- if let Some(end_time) = (end_time) {
- iter.take_while(|&(t, _)| t <= end_time)
- }
- if let Some(photon_count) = (photon_count) {
- iter.take(photon_count)
- }
- };
- }
Add Comment
Please, Sign In to add comment