len_trait/index.rs
1//! Traits involving collections which index over a particular type.
2
3cfg_if! {
4 if #[cfg(feature = "std")] {
5 use std::ops;
6 } else {
7 use core::ops;
8 }
9}
10
11use self::ops::{Index, IndexMut, Range, RangeFrom, RangeFull, RangeTo};
12
13
14mod private {
15 pub trait Sealed {}
16 impl Sealed for str {}
17 impl<T> Sealed for [T] {}
18}
19
20
21/// Shorthand trait for collections which offer consistent, immutable slicing.
22///
23/// Here, "consistent" means that indexing is implemented for all of the `Range` types from the
24/// standard library, and the type returned by each of the slices is always the same.
25///
26/// Currently, because inclusive ranges are unstable, and ranges starting with an exclusive bound
27/// don't exist, this trait can't be implemented for anything other than `str` and `[T]`. Hopefully,
28/// this will change in the future.
29pub trait IndexRange<Idx>
30 : Index<Range<Idx>, Output = <Self as Index<RangeFull>>::Output>
31 + Index<RangeTo<Idx>, Output = <Self as Index<RangeFull>>::Output>
32 + Index<RangeFrom<Idx>, Output = <Self as Index<RangeFull>>::Output>
33 + Index<RangeFull>
34 + private::Sealed {
35}
36impl<T: ?Sized, Idx> IndexRange<Idx> for T
37where
38 T: Index<
39 Range<Idx>,
40 Output = <T as Index<RangeFull>>::Output,
41 >,
42 T: Index<
43 RangeTo<Idx>,
44 Output = <T as Index<RangeFull>>::Output,
45 >,
46 T: Index<
47 RangeFrom<Idx>,
48 Output = <T as Index<RangeFull>>::Output,
49 >,
50 T: Index<RangeFull>,
51 T: private::Sealed,
52{
53}
54
55/// Shorthand trait for collections which offer consistent, mutable slicing.
56///
57/// Here, "consistent" means that indexing is implemented for all of the `Range` types from the
58/// standard library, and the type returned by each of the slices is always the same.
59///
60/// Currently, because inclusive ranges are unstable, and ranges starting with an exclusive bound
61/// don't exist, this trait can't be implemented for anything other than `str` and `[T]`. Hopefully,
62/// this will change in the future.
63pub trait IndexRangeMut<Idx>
64 : IndexMut<Range<Idx>>
65 + IndexMut<RangeTo<Idx>>
66 + IndexMut<RangeFrom<Idx>>
67 + IndexMut<RangeFull>
68 + IndexRange<Idx> {
69}
70
71impl<T: ?Sized, Idx> IndexRangeMut<Idx> for T
72where
73 T: IndexMut<Range<Idx>>,
74 T: IndexMut<RangeTo<Idx>>,
75 T: IndexMut<RangeFrom<Idx>>,
76 T: IndexMut<RangeFull>,
77 T: IndexRange<Idx>,
78{
79}
80
81/// A trait for splitting a collection into two pieces at a given index.
82///
83/// Splitting a collection must take a constant amount of time and space.
84pub trait SplitAt<Idx>: IndexRange<Idx> {
85 /// Splits the collection into two pieces at the given index.
86 ///
87 /// # Panics
88 ///
89 /// Panics if `index` is invalid according to the collection.
90 fn split_at(
91 &self,
92 index: Idx,
93 ) -> (&<Self as Index<RangeFull>>::Output, &<Self as Index<RangeFull>>::Output);
94}
95
96/// A trait for splitting a collection into two mutable pieces at a given index.
97///
98/// Splitting a collection must take a constant amount of time and space.
99pub trait SplitAtMut<Idx>: IndexRangeMut<Idx> + SplitAt<Idx> {
100 /// Splits the collection into two mutable pieces at the given index.
101 ///
102 /// # Panics
103 ///
104 /// Panics if `index` is invalid according to the collection.
105 fn split_at_mut(
106 &mut self,
107 index: Idx,
108 ) -> (&mut <Self as Index<RangeFull>>::Output, &mut <Self as Index<RangeFull>>::Output);
109}