1use crate::MergableSpan;
2
3#[derive(Debug, Clone)]
7pub struct MergeIter<I: Iterator> {
8 next: Option<I::Item>,
9 iter: I
10}
11
12pub fn merge_items<I: Iterator>(iter: I) -> MergeIter<I> {
13 MergeIter::new(iter)
14}
15
16impl<I: Iterator> MergeIter<I> {
17 pub fn new(iter: I) -> Self {
18 Self {
19 next: None,
20 iter
21 }
22 }
23}
24
25impl<I, X> Iterator for MergeIter<I>
26where
27 I: Iterator<Item = X>,
28 X: MergableSpan
29{
30 type Item = X;
31
32 fn next(&mut self) -> Option<Self::Item> {
33 let mut this_val = match self.next.take() {
34 Some(val) => val,
35 None => {
36 match self.iter.next() {
37 Some(val) => val,
38 None => { return None; }
39 }
40 }
41 };
42
43 for val in &mut self.iter {
44 if this_val.can_append(&val) {
45 this_val.append(val);
46 } else {
47 self.next = Some(val);
48 break;
49 }
50 }
51
52 Some(this_val)
53 }
54
55 fn size_hint(&self) -> (usize, Option<usize>) {
56 let (lower, upper) = self.iter.size_hint();
57 (lower.min(1), upper)
58 }
59}
60
61pub trait MergeableIterator<X: MergableSpan>: Iterator<Item = X> where Self: Sized {
62 fn merge_spans(self) -> MergeIter<Self>;
63}
64
65impl<X, I> MergeableIterator<X> for I
66where I: Iterator<Item=X>, X: MergableSpan, Self: Sized
67{
68 fn merge_spans(self) -> MergeIter<Self> {
69 MergeIter::new(self)
70 }
71}
72
73#[cfg(test)]
74mod test {
75 use super::merge_items;
76 use crate::RleRun;
77
78 #[test]
79 fn test_merge_iter() {
80 let empty: Vec<RleRun<u32>> = vec![];
81 assert_eq!(merge_items(empty.into_iter()).collect::<Vec<_>>(), vec![]);
82
83 let one = vec![RleRun { val: 5, len: 1 }];
84 assert_eq!(merge_items(one.into_iter()).collect::<Vec<_>>(), vec![RleRun { val: 5, len: 1 }]);
85
86 let two_split = vec![RleRun { val: 5, len: 1 }, RleRun { val: 15, len: 1 }];
87 assert_eq!(merge_items(two_split.iter().copied()).collect::<Vec<_>>(), two_split);
88
89 let two_merged = vec![RleRun { val: 5, len: 1 }, RleRun { val: 5, len: 2 }];
90 assert_eq!(merge_items(two_merged.iter().copied()).collect::<Vec<_>>(), vec![RleRun { val: 5, len: 3 }]);
91 }
92}