1#![warn(missing_docs)]
3
4#[doc(no_inline)]
5pub use std::ops::{
6 Bound, Range, RangeBounds, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
7};
8
9pub trait FixedRangeBounds<T: ?Sized> {
11 fn start_bound(&self) -> FixedBound<&T>;
13 fn end_bound(&self) -> FixedBound<&T>;
15}
16
17pub enum FixedBound<T> {
19 Included(T),
21 Unbounded,
23}
24
25impl<T> FixedRangeBounds<T> for RangeInclusive<T> {
26 fn start_bound(&self) -> FixedBound<&T> {
27 FixedBound::Included(self.start())
28 }
29 fn end_bound(&self) -> FixedBound<&T> {
30 FixedBound::Included(self.end())
31 }
32}
33
34impl<T> FixedRangeBounds<T> for RangeFull {
35 fn start_bound(&self) -> FixedBound<&T> {
36 FixedBound::Unbounded
37 }
38 fn end_bound(&self) -> FixedBound<&T> {
39 FixedBound::Unbounded
40 }
41}
42
43impl<T> FixedRangeBounds<T> for RangeFrom<T> {
44 fn start_bound(&self) -> FixedBound<&T> {
45 FixedBound::Included(&self.start)
46 }
47 fn end_bound(&self) -> FixedBound<&T> {
48 FixedBound::Unbounded
49 }
50}
51
52impl<T> FixedRangeBounds<T> for RangeToInclusive<T> {
53 fn start_bound(&self) -> FixedBound<&T> {
54 FixedBound::Unbounded
55 }
56 fn end_bound(&self) -> FixedBound<&T> {
57 FixedBound::Included(&self.end)
58 }
59}
60
61pub trait IndexRangeExt {
63 fn index_range<R>(self, range: R) -> Range<usize>
65 where
66 R: RangeBounds<usize>;
67}
68
69impl IndexRangeExt for usize {
70 fn index_range<R>(self, range: R) -> Range<usize>
71 where
72 R: RangeBounds<usize>,
73 {
74 Range {
75 start: match range.start_bound() {
76 Bound::Included(&i) => i,
77 Bound::Excluded(&i) => i + 1,
78 Bound::Unbounded => 0,
79 },
80 end: match range.end_bound() {
81 Bound::Included(&i) => i + 1,
82 Bound::Excluded(&i) => i,
83 Bound::Unbounded => self,
84 },
85 }
86 }
87}