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
use agilulf_protocol::Slice;
use std::cmp::Ordering;
use std::iter::Peekable;

pub struct MergeIter<T: Iterator<Item = (Slice, Slice)>> {
    iters: Vec<Peekable<T>>,
}

impl<T: Iterator<Item = (Slice, Slice)>> Iterator for MergeIter<T> {
    type Item = (Slice, Slice);

    fn next(&mut self) -> Option<Self::Item> {
        let mut tmp_ret: Option<(Slice, Slice)> = None;
        let mut min_index = 0;
        for (index, iter) in self.iters.iter_mut().enumerate() {
            let item = iter.peek();
            match item {
                Some(item) => match &tmp_ret {
                    None => {
                        tmp_ret = Some((item.0.clone(), item.1.clone()));
                        min_index = index;
                    }
                    Some(ret) => {
                        let cmp = ret.cmp(item);
                        match cmp {
                            Ordering::Less => {}
                            Ordering::Equal => {
                                while let Some(content) = iter.peek() {
                                    if content == ret {
                                        iter.next();
                                    } else {
                                        break;
                                    }
                                }
                                continue;
                            }
                            Ordering::Greater => {
                                tmp_ret = Some((item.0.clone(), item.1.clone()));
                                min_index = index;
                            }
                        }
                    }
                },
                None => {}
            }
        }

        while let Some(content) = self.iters[min_index].peek() {
            match tmp_ret.as_ref() {
                Some(ret) => {
                    if ret == content {
                        self.iters[min_index].next();
                    }
                }
                None => {
                    break;
                }
            }
        }

        tmp_ret
    }
}

pub fn merge_iter<T>(iters: Vec<T>) -> MergeIter<T>
where
    T: Iterator<Item = (Slice, Slice)>,
{
    MergeIter {
        iters: iters.into_iter().map(|item| item.peekable()).collect(),
    }
}