orx_iterable/transformations/
cloning_iterable.rs

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
use crate::Iterable;

/// An iterable created from an [`Iterator`] which can be [`Clone`]d.
///
/// Every time the `iter()` method of the iterable is called, it simply returns a clone
/// of the wrapped iterator, allowing for multiple iterations over the data.
///
/// # Example
///
/// ```
/// use orx_iterable::*;
///
/// let numbers = vec![1, 10, 7, 6, 3, 8, 2];
///
/// // evens is an `Iterator` which can be iterated over only once
/// let evens = numbers.iter().filter(|x| *x % 2 == 0);
///
/// // evens below is an `Iterable` which can be iterated over many times
/// let evens = numbers.iter().filter(|x| *x % 2 == 0).into_iterable();
///
/// assert_eq!(4, evens.iter().count());
/// assert_eq!(26, evens.iter().sum());
/// assert_eq!(Some(&2), evens.iter().min());
/// assert_eq!(Some(&10), evens.iter().max());
/// ```
pub struct CloningIterable<I>(I)
where
    I: Iterator + Clone;

impl<I> Iterable for CloningIterable<I>
where
    I: Iterator + Clone,
{
    type Item = I::Item;

    type Iter = I;

    fn iter(&self) -> Self::Iter {
        self.0.clone()
    }
}

/// Trait to transform types implementing `Iterator + Clone` into an `Iterable`.
///
/// Resulting iterable is of type [`CloningIterable`].
pub trait IntoCloningIterable: Iterator + Clone {
    /// Transforms this type implementing `Iterator + Clone` into an `Iterable`.
    ///
    /// Resulting iterable is of type [`CloningIterable`].
    fn into_iterable(self) -> CloningIterable<Self> {
        CloningIterable(self)
    }
}

impl<I> IntoCloningIterable for I where I: Iterator + Clone {}