tree_table/utils/
consecutive_ranges.rs1pub struct ConsecutiveRangesBorrowed<'a, I>
4where
5 I: Iterator<Item = &'a usize>,
6{
7 iter: I,
8 start: Option<usize>,
9 prev: Option<usize>,
10}
11
12impl<'a, I> Iterator for ConsecutiveRangesBorrowed<'a, I>
13where
14 I: Iterator<Item = &'a usize>,
15{
16 type Item = (usize, usize); fn next(&mut self) -> Option<Self::Item> {
19 let (current_start, mut current_prev) = match (self.start, self.prev) {
20 (Some(start), Some(prev)) => (start, prev),
21 (None, None) => {
22 if let Some(&first) = self.iter.next() {
23 self.start = Some(first);
24 self.prev = Some(first);
25 (first, first)
26 } else {
27 return None;
28 }
29 }
30 _ => unreachable!("start and prev should both be Some or both be None"),
31 };
32
33 loop {
34 match self.iter.next() {
35 Some(&curr) => {
36 if curr > current_prev + 1 {
37 let range = (current_start, current_prev);
39 self.start = Some(curr);
40 self.prev = Some(curr);
41 return Some(range);
42 } else {
43 current_prev = curr;
44 self.prev = Some(curr);
45 }
46 }
47 None => {
48 let range = (current_start, current_prev);
50 self.start = None;
51 self.prev = None;
52 return Some(range);
53 }
54 }
55 }
56 }
57}
58
59pub fn consecutive_ranges_borrowed<'a, I>(iter: I) -> ConsecutiveRangesBorrowed<'a, I>
60where
61 I: Iterator<Item = &'a usize>,
62{
63 ConsecutiveRangesBorrowed {
64 iter,
65 start: None,
66 prev: None,
67 }
68}
69
70pub struct ConsecutiveRangesOwned<I>
73where
74 I: Iterator<Item = usize>,
75{
76 iter: I,
77 start: Option<usize>,
78 prev: Option<usize>,
79}
80
81impl<I> Iterator for ConsecutiveRangesOwned<I>
82where
83 I: Iterator<Item = usize>,
84{
85 type Item = (usize, usize); fn next(&mut self) -> Option<Self::Item> {
88 let (current_start, mut current_prev) = match (self.start, self.prev) {
89 (Some(start), Some(prev)) => (start, prev),
90 (None, None) => {
91 if let Some(first) = self.iter.next() {
92 self.start = Some(first);
93 self.prev = Some(first);
94 (first, first)
95 } else {
96 return None;
97 }
98 }
99 _ => unreachable!("start and prev should both be Some or both be None"),
100 };
101
102 loop {
103 match self.iter.next() {
104 Some(curr) => {
105 if curr > current_prev + 1 {
106 let range = (current_start, current_prev); self.start = Some(curr);
108 self.prev = Some(curr);
109 return Some(range);
110 } else {
111 current_prev = curr;
112 self.prev = Some(curr);
113 }
114 }
115 None => {
116 let range = (current_start, current_prev); self.start = None;
118 self.prev = None;
119 return Some(range);
120 }
121 }
122 }
123 }
124}
125
126pub fn consecutive_ranges_owned<I>(iter: I) -> ConsecutiveRangesOwned<I>
127where
128 I: Iterator<Item = usize>,
129{
130 ConsecutiveRangesOwned {
131 iter,
132 start: None,
133 prev: None,
134 }
135}