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
/// Middleware-enabled iterator
///
/// This struct wraps an iterator and applies a middleware function to each item yielded by the iterator
pub struct Iterware<I, F> {
    iter: I,
    f: F,
}

impl<I: Iterator, F> Iterator for Iterware<I, F>
    where
        F: Fn(&I::Item) -> (),
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        match self.iter.next() {
            Some(t) => {
                (self.f)(&t);
                Some(t)
            }
            None => None,
        }
    }
}

/// Method chaining trait
/// Import to add the `middleware` method to iterators.
/// See the [`middleware` method](#tymethod.middleware) for more example usage.
pub trait IteratorMiddleware<I, F> {
    /// use method chaining to add middleware to your iterators
    ///
    ///```rust
    /// use iterware::IteratorMiddleware;
    /// let values = vec![1, 2, 3, 4, 5];
    /// let sum = values
    ///     .into_iter()
    ///     .middleware(|value: &i32| println!("Adding value {}", value))
    ///     .sum::<i32>();
    ///
    /// assert_eq!(sum, 15);
    ///```
    fn middleware(self, f: F) -> Iterware<I, F>;
}

impl<I, F> IteratorMiddleware<I, F> for I
    where
        I: Iterator,
        F: Fn(&I::Item) -> (),
{
    fn middleware(self, f: F) -> Iterware<I, F> {
        Iterware { iter: self, f }
    }
}

#[cfg(test)]
mod tests {
    use crate::IteratorMiddleware;

    #[test]
    fn test_borrow() {
        let values = vec![1, 2, 3, 4, 5];

        let sum: i32 = values
            .into_iter()
            .middleware(|value| println!("Adding value {}", value))
            .sum();

        println!("The sum is {}", sum);

        assert_eq!(sum, 15);
    }
}