orx_iterable/transformations/
cloning_iterable.rs

1use crate::Iterable;
2
3/// An iterable created from an [`Iterator`] which can be [`Clone`]d.
4///
5/// Every time the `iter()` method of the iterable is called, it simply returns a clone
6/// of the wrapped iterator, allowing for multiple iterations over the data.
7///
8/// # Example
9///
10/// ```
11/// use orx_iterable::*;
12///
13/// let numbers = vec![1, 10, 7, 6, 3, 8, 2];
14///
15/// // evens is an `Iterator` which can be iterated over only once
16/// let evens = numbers.iter().filter(|x| *x % 2 == 0);
17///
18/// // evens below is an `Iterable` which can be iterated over many times
19/// let evens = numbers.iter().filter(|x| *x % 2 == 0).into_iterable();
20///
21/// assert_eq!(4, evens.iter().count());
22/// assert_eq!(26, evens.iter().sum());
23/// assert_eq!(Some(&2), evens.iter().min());
24/// assert_eq!(Some(&10), evens.iter().max());
25/// ```
26pub struct CloningIterable<I>(I)
27where
28    I: Iterator + Clone;
29
30impl<I> Iterable for CloningIterable<I>
31where
32    I: Iterator + Clone,
33{
34    type Item = I::Item;
35
36    type Iter = I;
37
38    fn iter(&self) -> Self::Iter {
39        self.0.clone()
40    }
41}
42
43/// Trait to transform types implementing `Iterator + Clone` into an `Iterable`.
44///
45/// Resulting iterable is of type [`CloningIterable`].
46pub trait IntoCloningIterable: Iterator + Clone {
47    /// Transforms this type implementing `Iterator + Clone` into an `Iterable`.
48    ///
49    /// Resulting iterable is of type [`CloningIterable`].
50    fn into_iterable(self) -> CloningIterable<Self> {
51        CloningIterable(self)
52    }
53}
54
55impl<I> IntoCloningIterable for I where I: Iterator + Clone {}