foreach 0.3.0

ForEach trait and for_each! macro allow you to use iterator inside iteration loop, which is not posible when using for-in loop.
Documentation
//! 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;
            }
        }
    };
}