bstr/
slice_index.rs

1use core::ops;
2
3use bstr::BStr;
4
5/// Ensure that callers cannot implement `SliceIndex` by making an
6/// umplementable trait its super trait.
7pub trait Sealed {}
8impl Sealed for usize {}
9impl Sealed for ops::Range<usize> {}
10impl Sealed for ops::RangeTo<usize> {}
11impl Sealed for ops::RangeFrom<usize> {}
12impl Sealed for ops::RangeFull {}
13impl Sealed for ops::RangeInclusive<usize> {}
14impl Sealed for ops::RangeToInclusive<usize> {}
15
16/// A trait that parameterizes the different types of indexing a byte string.
17///
18/// In general, this trait makes it possible to define generic routines like
19/// `get` that can accept either single positions or ranges, and return single
20/// bytes or slices, respectively.
21///
22/// This trait is sealed such that callers cannot implement it. In general,
23/// callers should not need to interact with this trait directly unless you're
24/// defining generic functions that index or slice a byte string.
25pub trait SliceIndex: Sealed {
26    /// The output type returned by methods. For indexing by position, this
27    /// is always a single byte (`u8`). For ranges, this is always a slice
28    /// (`BStr`).
29    type Output: ?Sized;
30
31    /// Returns a shared reference to the output at this location, if in
32    /// bounds.
33    fn get(self, slice: &BStr) -> Option<&Self::Output>;
34
35    /// Returns a mutable reference to the output at this location, if in
36    /// bounds.
37    fn get_mut(self, slice: &mut BStr) -> Option<&mut Self::Output>;
38
39    /// Returns a shared reference to the output at this location, without
40    /// performing any bounds checking.
41    unsafe fn get_unchecked(self, slice: &BStr) -> &Self::Output;
42
43    /// Returns a mutable reference to the output at this location, without
44    /// performing any bounds checking.
45    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut Self::Output;
46
47    /// Returns a shared reference to the output at this location, panicking
48    /// if out of bounds.
49    fn index(self, slice: &BStr) -> &Self::Output;
50
51    /// Returns a mutable reference to the output at this location, panicking
52    /// if out of bounds.
53    fn index_mut(self, slice: &mut BStr) -> &mut Self::Output;
54}
55
56impl SliceIndex for usize {
57    type Output = u8;
58
59    #[inline]
60    fn get(self, slice: &BStr) -> Option<&u8> {
61        slice.as_bytes().get(self)
62    }
63
64    #[inline]
65    fn get_mut(self, slice: &mut BStr) -> Option<&mut u8> {
66        slice.as_bytes_mut().get_mut(self)
67    }
68
69    #[inline]
70    unsafe fn get_unchecked(self, slice: &BStr) -> &u8 {
71        slice.as_bytes().get_unchecked(self)
72    }
73
74    #[inline]
75    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut u8 {
76        slice.as_bytes_mut().get_unchecked_mut(self)
77    }
78
79    #[inline]
80    fn index(self, slice: &BStr) -> &u8 {
81        &slice.as_bytes()[self]
82    }
83
84    #[inline]
85    fn index_mut(self, slice: &mut BStr) -> &mut u8 {
86        &mut slice.as_bytes_mut()[self]
87    }
88}
89
90impl SliceIndex for ops::Range<usize> {
91    type Output = BStr;
92
93    #[inline]
94    fn get(self, slice: &BStr) -> Option<&BStr> {
95        slice.as_bytes().get(self).map(BStr::new)
96    }
97
98    #[inline]
99    fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> {
100        slice.as_bytes_mut().get_mut(self).map(BStr::new_mut)
101    }
102
103    #[inline]
104    unsafe fn get_unchecked(self, slice: &BStr) -> &BStr {
105        BStr::new(slice.as_bytes().get_unchecked(self))
106    }
107
108    #[inline]
109    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr {
110        BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self))
111    }
112
113    #[inline]
114    fn index(self, slice: &BStr) -> &BStr {
115        &slice[self]
116    }
117
118    #[inline]
119    fn index_mut(self, slice: &mut BStr) -> &mut BStr {
120        &mut slice[self]
121    }
122}
123
124impl SliceIndex for ops::RangeTo<usize> {
125    type Output = BStr;
126
127    #[inline]
128    fn get(self, slice: &BStr) -> Option<&BStr> {
129        slice.as_bytes().get(self).map(BStr::new)
130    }
131
132    #[inline]
133    fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> {
134        slice.as_bytes_mut().get_mut(self).map(BStr::new_mut)
135    }
136
137    #[inline]
138    unsafe fn get_unchecked(self, slice: &BStr) -> &BStr {
139        BStr::new(slice.as_bytes().get_unchecked(self))
140    }
141
142    #[inline]
143    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr {
144        BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self))
145    }
146
147    #[inline]
148    fn index(self, slice: &BStr) -> &BStr {
149        &slice[self]
150    }
151
152    #[inline]
153    fn index_mut(self, slice: &mut BStr) -> &mut BStr {
154        &mut slice[self]
155    }
156}
157
158impl SliceIndex for ops::RangeFrom<usize> {
159    type Output = BStr;
160
161    #[inline]
162    fn get(self, slice: &BStr) -> Option<&BStr> {
163        slice.as_bytes().get(self).map(BStr::new)
164    }
165
166    #[inline]
167    fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> {
168        slice.as_bytes_mut().get_mut(self).map(BStr::new_mut)
169    }
170
171    #[inline]
172    unsafe fn get_unchecked(self, slice: &BStr) -> &BStr {
173        BStr::new(slice.as_bytes().get_unchecked(self))
174    }
175
176    #[inline]
177    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr {
178        BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self))
179    }
180
181    #[inline]
182    fn index(self, slice: &BStr) -> &BStr {
183        &slice[self]
184    }
185
186    #[inline]
187    fn index_mut(self, slice: &mut BStr) -> &mut BStr {
188        &mut slice[self]
189    }
190}
191
192impl SliceIndex for ops::RangeFull {
193    type Output = BStr;
194
195    #[inline]
196    fn get(self, slice: &BStr) -> Option<&BStr> {
197        slice.as_bytes().get(self).map(BStr::new)
198    }
199
200    #[inline]
201    fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> {
202        slice.as_bytes_mut().get_mut(self).map(BStr::new_mut)
203    }
204
205    #[inline]
206    unsafe fn get_unchecked(self, slice: &BStr) -> &BStr {
207        BStr::new(slice.as_bytes().get_unchecked(self))
208    }
209
210    #[inline]
211    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr {
212        BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self))
213    }
214
215    #[inline]
216    fn index(self, slice: &BStr) -> &BStr {
217        &slice[self]
218    }
219
220    #[inline]
221    fn index_mut(self, slice: &mut BStr) -> &mut BStr {
222        &mut slice[self]
223    }
224}
225
226impl SliceIndex for ops::RangeInclusive<usize> {
227    type Output = BStr;
228
229    #[inline]
230    fn get(self, slice: &BStr) -> Option<&BStr> {
231        slice.as_bytes().get(self).map(BStr::new)
232    }
233
234    #[inline]
235    fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> {
236        slice.as_bytes_mut().get_mut(self).map(BStr::new_mut)
237    }
238
239    #[inline]
240    unsafe fn get_unchecked(self, slice: &BStr) -> &BStr {
241        BStr::new(slice.as_bytes().get_unchecked(self))
242    }
243
244    #[inline]
245    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr {
246        BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self))
247    }
248
249    #[inline]
250    fn index(self, slice: &BStr) -> &BStr {
251        &slice[self]
252    }
253
254    #[inline]
255    fn index_mut(self, slice: &mut BStr) -> &mut BStr {
256        &mut slice[self]
257    }
258}
259
260impl SliceIndex for ops::RangeToInclusive<usize> {
261    type Output = BStr;
262
263    #[inline]
264    fn get(self, slice: &BStr) -> Option<&BStr> {
265        slice.as_bytes().get(self).map(BStr::new)
266    }
267
268    #[inline]
269    fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> {
270        slice.as_bytes_mut().get_mut(self).map(BStr::new_mut)
271    }
272
273    #[inline]
274    unsafe fn get_unchecked(self, slice: &BStr) -> &BStr {
275        BStr::new(slice.as_bytes().get_unchecked(self))
276    }
277
278    #[inline]
279    unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr {
280        BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self))
281    }
282
283    #[inline]
284    fn index(self, slice: &BStr) -> &BStr {
285        &slice[self]
286    }
287
288    #[inline]
289    fn index_mut(self, slice: &mut BStr) -> &mut BStr {
290        &mut slice[self]
291    }
292}