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
//! Some useful features shared by more than one other module or impossible to class in one of these

/// A resettable iterator. It means that calling a `reset` method will set the iterator to the first position
pub trait ResettableIterator: Iterator {
    /// Resets the iterator to its initial state when called
    fn reset(&mut self);

    /// Creates a new iterator from the current one and reset it
    fn reset_clone(&self) -> Self
    where
        Self: Clone,
    {
        let mut new = self.clone();
        new.reset();
        new
    }

    /// Creates a ResettableMap from the current iterator
    fn resettable_map<F, R>(self, callback: F) -> self::ResettableMap<Self, F>
    where
        F: FnMut(Self::Item) -> R,
        Self: Sized,
    {
        ResettableMap {
            iterator: self,
            callback,
        }
    }
}

/// A resettable version of `std::iter::Map`. A simple trait implementation is not suitable because it requires to get access to private elements of `std::iter::Map` like the iterator stored
/// 
/// You can use it like you would use `std::iter::Map` but it implements the `ResettableIterator` trait too
pub struct ResettableMap<I, F> {
    iterator: I,
    callback: F,
}

impl<I, F, R> Iterator for ResettableMap<I, F>
where
    I: Iterator,
    F: FnMut(I::Item) -> R,
{
    type Item = R;

    fn next(&mut self) -> Option<R> {
        let item = self.iterator.next()?;
        let result = (self.callback)(item);

        Some(result)
    }
}

impl<I, F, R> self::ResettableIterator for ResettableMap<I, F>
where
    I: self::ResettableIterator,
    F: FnMut(I::Item) -> R,
{
    fn reset(&mut self) {
        self.iterator.reset();
    }
}

impl<I, F, R> crate::child::ChildIterator for ResettableMap<I, F>
where
    I: Iterator,
    F: FnMut(I::Item) -> R,
{
    type Parent = I;

    fn release_parent(self) -> I {
        self.iterator
    }

    fn get_parent_mut(&mut self) -> &mut I {
        &mut self.iterator
    }

    fn get_parent(&self) -> &I {
        &self.iterator
    }
}