1use core::ops;
6
7#[track_caller]
8fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
9 panic!(
10 "slice end index is out of range for slice\nrange end index {index} out of range for slice of length {len}",
11 )
12}
13#[track_caller]
14fn slice_index_order_fail(index: usize, end: usize) -> ! {
15 panic!("slice index start is larger than end\nslice index starts at {index} but ends at {end}",)
16}
17#[track_caller]
18const fn slice_start_index_overflow_fail() -> ! {
19 panic!("attempted to index slice from after maximum usize");
20}
21#[track_caller]
22const fn slice_end_index_overflow_fail() -> ! {
23 panic!("attempted to index slice up to maximum usize");
24}
25
26#[track_caller]
27pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
28where
29 R: ops::RangeBounds<usize>,
30{
31 let len = bounds.end;
32
33 let start = match range.start_bound() {
34 ops::Bound::Included(&start) => start,
35 ops::Bound::Excluded(start) => {
36 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
37 }
38 ops::Bound::Unbounded => 0,
39 };
40
41 let end = match range.end_bound() {
42 ops::Bound::Included(end) => {
43 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
44 }
45 ops::Bound::Excluded(&end) => end,
46 ops::Bound::Unbounded => len,
47 };
48
49 if start > end {
50 slice_index_order_fail(start, end);
51 }
52 if end > len {
53 slice_end_index_len_fail(end, len);
54 }
55
56 ops::Range { start, end }
57}