fast_pull/base/
progress.rs1use core::ops::Range;
4
5pub type ProgressEntry = Range<u64>;
9
10pub trait Total {
12 fn total(&self) -> u64;
14}
15
16impl Total for ProgressEntry {
17 #[allow(clippy::inline_always)]
18 #[inline(always)]
19 fn total(&self) -> u64 {
20 self.end.saturating_sub(self.start)
21 }
22}
23
24impl Total for Vec<ProgressEntry> {
33 fn total(&self) -> u64 {
34 self.iter().map(Total::total).sum()
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn progress_entry_total() {
44 assert_eq!((0..0).total(), 0);
45 assert_eq!((5..10).total(), 5);
46 assert_eq!((3..3).total(), 0);
47 let reversed = core::ops::Range { start: 10, end: 5 };
49 assert_eq!(reversed.total(), 0);
50 }
51
52 #[test]
53 fn vec_progress_total() {
54 #![allow(clippy::single_range_in_vec_init)]
55 let v: Vec<ProgressEntry> = vec![1..5, 8..10, 12..15];
56 assert_eq!(v.total(), 9);
57 let empty: Vec<ProgressEntry> = vec![];
58 assert_eq!(empty.total(), 0);
59 }
60
61 #[test]
62 fn progress_entry_total_reversed_ranges_are_safe() {
63 assert_eq!((core::ops::Range { start: 10, end: 5 }).total(), 0);
65 assert_eq!(
66 (core::ops::Range {
67 start: u64::MAX,
68 end: 0
69 })
70 .total(),
71 0
72 );
73 assert_eq!(
74 (core::ops::Range {
75 start: 100,
76 end: 99
77 })
78 .total(),
79 0
80 );
81 assert_eq!((core::ops::Range { start: 1, end: 0 }).total(), 0);
82 }
83
84 #[test]
85 fn progress_entry_total_extreme_and_degenerate() {
86 assert_eq!((0..u64::MAX).total(), u64::MAX);
88 assert_eq!((u64::MAX..u64::MAX).total(), 0);
89 assert_eq!((42..42).total(), 0);
90 assert_eq!((0..0).total(), 0);
91 }
92
93 #[test]
94 fn vec_progress_total_counts_overlap_twice() {
95 #![allow(clippy::single_range_in_vec_init)]
96 let v: Vec<ProgressEntry> = vec![0..5, 3..10];
99 assert_eq!(v.total(), 12);
101 }
102
103 #[test]
104 #[cfg_attr(debug_assertions, should_panic)]
105 #[allow(clippy::should_panic_without_expect)]
106 fn vec_progress_total_overflow_is_unchecked() {
107 let v: Vec<ProgressEntry> = vec![0..u64::MAX, 0..1];
110 let _ = v.total(); }
112}