graph_api_simplegraph/graph/
iter.rs

1use std::ops::Range;
2
3pub(crate) enum RangeOrNoneIterator<T, Incr> {
4    None {
5        exhausted: bool,
6    },
7    Range {
8        current: T,
9        range: Range<T>,
10        incr: Incr,
11    },
12}
13
14impl<T, Incr> RangeOrNoneIterator<T, Incr>
15where
16    T: Copy,
17    Incr: Fn(T) -> T,
18{
19    pub(crate) fn new(range: Option<Range<T>>, incr: Incr) -> RangeOrNoneIterator<T, Incr> {
20        match range {
21            None => RangeOrNoneIterator::None { exhausted: false },
22            Some(r) => RangeOrNoneIterator::Range {
23                current: r.start,
24                range: r,
25                incr,
26            },
27        }
28    }
29}
30
31impl<T, Incr> Iterator for RangeOrNoneIterator<T, Incr>
32where
33    T: Copy + Clone + Ord,
34    Incr: Fn(T) -> T,
35{
36    type Item = Option<T>;
37
38    fn next(&mut self) -> Option<Self::Item> {
39        match self {
40            RangeOrNoneIterator::None { exhausted } => {
41                if *exhausted {
42                    None
43                } else {
44                    *exhausted = true;
45                    Some(None)
46                }
47            }
48            RangeOrNoneIterator::Range {
49                current,
50                range,
51                incr,
52            } => {
53                if *current < range.end {
54                    let current_copy = *current;
55                    *current = incr(current_copy);
56                    Some(Some(current_copy))
57                } else {
58                    None
59                }
60            }
61        }
62    }
63}