1use crate::ProgressEntry;
2
3pub trait Merge {
4 fn merge_progress(&mut self, new: ProgressEntry);
5}
6
7impl Merge for Vec<ProgressEntry> {
8 fn merge_progress(&mut self, new: ProgressEntry) {
9 let i = self.partition_point(|x| x.end < new.start);
10 if i == self.len() {
11 self.push(new);
12 return;
13 }
14 if self[i].start <= new.start && self[i].end >= new.end {
15 return;
16 }
17 let mut current_merge = new;
18 let mut j = i;
19 while j < self.len() {
20 let entry = &self[j];
21 if entry.start > current_merge.end {
22 break;
23 }
24 current_merge.start = current_merge.start.min(entry.start);
25 current_merge.end = current_merge.end.max(entry.end);
26 j += 1;
27 }
28 if j > i {
29 self.drain(i..j);
30 }
31 self.insert(i, current_merge);
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38
39 #[test]
40 fn test_merge() {
41 #[allow(clippy::single_range_in_vec_init)]
42 let mut v = vec![1..5, 8..10];
43 v.merge_progress(5..10);
44 assert_eq!(v, vec![1..10]);
45 v.merge_progress(10..20);
46 assert_eq!(v, vec![1..20]);
47 v.merge_progress(30..40);
48 assert_eq!(v, vec![1..20, 30..40]);
49 v.merge_progress(21..40);
50 assert_eq!(v, vec![1..20, 21..40]);
51 v.merge_progress(19..21);
52 assert_eq!(v, vec![1..40]);
53 v.merge_progress(50..60);
54 assert_eq!(v, vec![1..40, 50..60]);
55 v.merge_progress(50..60);
56 assert_eq!(v, vec![1..40, 50..60]);
57 v.merge_progress(52..60);
58 assert_eq!(v, vec![1..40, 50..60]);
59 v.merge_progress(52..53);
60 assert_eq!(v, vec![1..40, 50..60]);
61 v.merge_progress(52..61);
62 assert_eq!(v, vec![1..40, 50..61]);
63 v.merge_progress(62..70);
64 assert_eq!(v, vec![1..40, 50..61, 62..70]);
65 v.merge_progress(40..62);
66 assert_eq!(v, vec![1..70]);
67 v.merge_progress(72..82);
68 assert_eq!(v, vec![1..70, 72..82]);
69 v.merge_progress(0..90);
70 assert_eq!(v, vec![0..90]);
71 }
72}