1use core::ops::{Bound, RangeBounds};
2
3#[inline]
5pub fn start_bound_to_idx<K, F, G>(
6 bound: Bound<&K>,
7 len: usize,
8 lower_bound: F,
9 upper_bound: G,
10) -> usize
11where
12 F: Fn(&K) -> usize,
13 G: Fn(&K) -> usize,
14{
15 match bound {
16 Bound::Included(key) => lower_bound(key).min(len),
17 Bound::Excluded(key) => upper_bound(key).min(len),
18 Bound::Unbounded => 0,
19 }
20}
21
22#[inline]
24pub fn end_bound_to_idx<K, F, G>(
25 bound: Bound<&K>,
26 len: usize,
27 lower_bound: F,
28 upper_bound: G,
29) -> usize
30where
31 F: Fn(&K) -> usize,
32 G: Fn(&K) -> usize,
33{
34 match bound {
35 Bound::Included(key) => upper_bound(key).min(len),
36 Bound::Excluded(key) => lower_bound(key).min(len),
37 Bound::Unbounded => len,
38 }
39}
40
41#[inline]
43pub fn range_to_indices<K, R, F, G>(
44 range: R,
45 len: usize,
46 lower_bound: F,
47 upper_bound: G,
48) -> (usize, usize)
49where
50 R: RangeBounds<K>,
51 F: Fn(&K) -> usize + Copy,
52 G: Fn(&K) -> usize + Copy,
53{
54 let start = start_bound_to_idx(range.start_bound(), len, lower_bound, upper_bound);
55 let end = end_bound_to_idx(range.end_bound(), len, lower_bound, upper_bound);
56 (start, end.max(start))
57}