exocore_core/utils/
range.rs

1use std::ops::Range;
2
3pub fn are_continuous<'a, I, T: 'a + Ord + Copy + Eq>(iter: I) -> bool
4where
5    I: Iterator<Item = &'a Range<T>>,
6{
7    get_gaps(iter).is_empty()
8}
9
10pub fn get_gaps<'a, I, T: 'a + Ord + Copy + Eq>(iter: I) -> Vec<Range<T>>
11where
12    I: Iterator<Item = &'a Range<T>>,
13{
14    let mut sorted: Vec<&Range<T>> = iter.collect();
15    sorted.sort_by(|a, b| a.start.partial_cmp(&b.start).unwrap());
16
17    let mut gaps = Vec::new();
18    for i in 1..sorted.len() {
19        let left = &sorted[i - 1];
20        let right = &sorted[i];
21        if left.end != right.start {
22            gaps.push(Range {
23                start: left.end,
24                end: right.start,
25            });
26        }
27    }
28
29    gaps
30}
31
32#[cfg(test)]
33mod test {
34    use super::*;
35
36    #[test]
37    fn test_find_gaps() {
38        let r1 = 10..20;
39        let r2 = 30..40;
40        let r3 = 40..50;
41        let r4 = 80..100;
42
43        let ranges = [r2, r1, r4, r3];
44        let gaps = get_gaps(ranges.iter());
45        assert_eq!(gaps, vec![20..30, 50..80]);
46        assert!(!are_continuous(ranges.iter()));
47
48        let r5 = 30..40;
49        let r6 = 40..50;
50        let ranges = [r5, r6];
51        assert!(are_continuous(ranges.iter()));
52    }
53}