1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
//! ForEach trait and for_each! macro allow you to use iterator inside iteration //! loop, which is not posible when using for-in loop. //! //! # Examples //! ``` //! # extern crate foreach; //! # use foreach::ForEach; //! # fn main() { //! let mut iter = 0..999; //! iter.foreach(|item, iter| { //! println!("item: {}", item); //! println!("next: {:?}", iter.next()); //! }); //! # } //! ``` //! //! ``` //! # extern crate foreach; //! # use foreach::ForEach; //! use foreach::Continue::*; //! # fn main() { //! let mut iter = 0..999; //! iter.foreach(|item, iter| { //! println!("item: {}", item); //! println!("next: {:?}", iter.next()); //! if item > 10 { //! return Break; //! } else { //! return ().into(); //! } //! }); //! # } //! ``` //! //! ``` //! # #[macro_use] extern crate foreach; //! # fn main() { //! let mut iter = 0..999; //! for_each!(item in iter { //! println!("item: {}", item); //! println!("next: {:?}", iter.next()); //! if item > 10 { //! break; //! } //! }); //! # } //! ``` use std::iter::Iterator; pub enum Continue { /// This is default value, it does not change anything. Continue, /// If this variant is returned, iteration ends. Break, } impl Default for Continue { fn default() -> Continue { Continue::Continue } } impl From<()> for Continue { /// Converts `()` to `Continue::Continue` fn from(_: ()) -> Continue { Continue::Continue } } /// Trait to simplify usage of iterator inside iteration loop. /// /// This trait is implemented for all iterators by default. pub trait ForEach: Iterator { /// Iterates over all items and executes given closure. /// /// This allows you to use iterator inside iteration loop, which is not /// posible when using for-in loop. /// /// See [crate-level docs](./index.html) for examples fn foreach<O, F>(&mut self, f: F) where O: Into<Continue>, F: FnMut(Self::Item, &mut Self) -> O; } impl<T: Iterator> ForEach for T { fn foreach<O, F>(&mut self, mut f: F) where O: Into<Continue>, F: FnMut(Self::Item, &mut Self) -> O, { loop { let item = self.next(); if let Some(item) = item { match f(item, self).into() { Continue::Break => break, _ => (), } } else { break; } } } } /// This macro allows you to use iterator inside iteration loop, which is not /// posible when using for-in loop. /// See [crate-level docs](./index.html) for examples #[macro_export] macro_rules! for_each { ($pat:pat in $iter:ident $code:block) => { loop { use std::iter::Iterator; let __for_each_item = Iterator::next(&mut $iter); if let Some($pat) = __for_each_item { $code } else { break; } } }; ($item:ident in $iter:ident $code:block) => { loop { use std::iter::Iterator; let $item = Iterator::next(&mut $iter); if let Some($item) = $item { $code } else { break; } } }; }