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
//! Custom iterators used by ink! IR types, abstractions and utilities.
/// An iterator where each successive item is taken from a wrapped iterator
/// which is computed from a source and a step expression.
pub struct IterSuccessors<
T, // The associated type of this iterator.
S, // The source type to which the step expression is applied to generate the iterated items.
I: Iterator<Item = T>, // The type of the wrapped iterator on which next is called.
F: FnMut(&S) -> Option<(Option<I>, S)>, // The type of the step expression function.
> {
/// The wrapped iterator.
next_iter: Option<I>,
/// The source input for computing the next iterator.
next_source: S,
/// The function applied at each step to generate the next iterator and source.
step_expression: F,
}
impl<T, S, I, F> IterSuccessors<T, S, I, F>
where
I: Iterator<Item = T>,
F: FnMut(&S) -> Option<(Option<I>, S)>,
{
/// Creates an iterator where each successive item is taken from a wrapped iterator
/// which is computed from a source and a step expression.
pub fn new(source: S, step_expression: F) -> Self {
Self {
next_iter: None,
next_source: source,
step_expression,
}
}
}
impl<T, S, I, F> Iterator for IterSuccessors<T, S, I, F>
where
I: Iterator<Item = T>,
F: FnMut(&S) -> Option<(Option<I>, S)>,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
// Return the next item in the wrapped iterator if any.
if let Some(next_iter) = &mut self.next_iter {
if let Some(next_item) = next_iter.next() {
return Some(next_item);
}
}
// Recurse if the step expression either returns the next iterator or the next source.
if let Some((next_iter, next_source)) = (self.step_expression)(&self.next_source) {
self.next_iter = next_iter;
self.next_source = next_source;
return self.next();
}
None
}
}