Skip to main content

realhydroper_utf16/
slice.rs

1// Based in https://github.com/getsentry/utf16string/blob/main/src/slicing.rs
2
3use std::ops::{Index, IndexMut, Range, RangeFull, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
4
5use super::{Utf16Str, Utf16String};
6
7mod private {
8    use super::*;
9
10    pub trait SealedSliceIndex {}
11
12    impl SealedSliceIndex for RangeFull {}
13    impl SealedSliceIndex for Range<usize> {}
14    impl SealedSliceIndex for RangeFrom<usize> {}
15    impl SealedSliceIndex for RangeTo<usize> {}
16    impl SealedSliceIndex for RangeInclusive<usize> {}
17    impl SealedSliceIndex for RangeToInclusive<usize> {}
18}
19
20pub trait SliceIndex<T>: private::SealedSliceIndex
21where
22    T: ?Sized,
23{
24    type Output: ?Sized;
25
26    fn get(self, slice: &T) -> Option<&Self::Output>;
27
28    fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
29
30    unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
31
32    unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
33
34    fn index(self, slice: &T) -> &Self::Output;
35
36    fn index_mut(self, slice: &mut T) -> &mut Self::Output;
37}
38
39impl SliceIndex<Utf16Str> for RangeFull {
40    type Output = Utf16Str;
41
42    #[inline]
43    fn get(self, slice: &Utf16Str) -> Option<&Self::Output> {
44        Some(slice)
45    }
46
47    #[inline]
48    fn get_mut(self, slice: &mut Utf16Str) -> Option<&mut Self::Output> {
49        Some(slice)
50    }
51
52    #[inline]
53    unsafe fn get_unchecked(self, slice: &Utf16Str) -> &Self::Output {
54        slice
55    }
56
57    #[inline]
58    unsafe fn get_unchecked_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
59        slice
60    }
61
62    #[inline]
63    fn index(self, slice: &Utf16Str) -> &Self::Output {
64        slice
65    }
66
67    #[inline]
68    fn index_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
69        slice
70    }
71}
72
73impl SliceIndex<Utf16Str> for Range<usize> {
74    type Output = Utf16Str;
75
76    #[inline]
77    fn get(self, slice: &Utf16Str) -> Option<&Self::Output> {
78        if self.start <= self.end && self.end <= slice.len() { Some(unsafe { self.get_unchecked(slice) }) } else { None }
79    }
80
81    #[inline]
82    fn get_mut(self, slice: &mut Utf16Str) -> Option<&mut Self::Output> {
83        if self.start <= self.end && self.end <= slice.len() { Some(unsafe { self.get_unchecked_mut(slice) }) } else { None }
84    }
85
86    #[inline]
87    unsafe fn get_unchecked(self, slice: &Utf16Str) -> &Self::Output {
88        let ptr = unsafe { slice.as_ptr().add(self.start) };
89        let len = self.end - self.start;
90        unsafe { Utf16Str::from_utf16_unchecked(std::slice::from_raw_parts(ptr, len)) }
91    }
92
93    #[inline]
94    unsafe fn get_unchecked_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
95        let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
96        let len = self.end - self.start;
97        unsafe { Utf16Str::from_utf16_unchecked_mut(std::slice::from_raw_parts_mut(ptr, len)) }
98    }
99
100    #[inline]
101    fn index(self, slice: &Utf16Str) -> &Self::Output {
102        self.get(slice).expect("slice index out of bounds")
103    }
104
105    #[inline]
106    fn index_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
107        self.get_mut(slice).expect("slice index out of bounds")
108    }
109}
110
111impl SliceIndex<Utf16Str> for RangeTo<usize> {
112    type Output = Utf16Str;
113
114    #[inline]
115    fn get(self, slice: &Utf16Str) -> Option<&Self::Output> {
116        if self.end <= slice.len() { Some(unsafe { self.get_unchecked(slice) }) } else { None }
117    }
118
119    #[inline]
120    fn get_mut(self, slice: &mut Utf16Str) -> Option<&mut Self::Output> {
121        if self.end <= slice.len() { Some(unsafe { self.get_unchecked_mut(slice) }) } else { None }
122    }
123
124    #[inline]
125    unsafe fn get_unchecked(self, slice: &Utf16Str) -> &Self::Output {
126        let ptr = slice.as_ptr();
127        unsafe { Utf16Str::from_utf16_unchecked(std::slice::from_raw_parts(ptr, self.end)) }
128    }
129
130    #[inline]
131    unsafe fn get_unchecked_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
132        let ptr = slice.as_mut_ptr();
133        unsafe { Utf16Str::from_utf16_unchecked_mut(std::slice::from_raw_parts_mut(ptr, self.end)) }
134    }
135
136    #[inline]
137    fn index(self, slice: &Utf16Str) -> &Self::Output {
138        self.get(slice).expect("slice index out of bounds")
139    }
140
141    #[inline]
142    fn index_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
143        self.get_mut(slice).expect("slice index out of bounds")
144    }
145}
146
147impl SliceIndex<Utf16Str> for RangeFrom<usize> {
148    type Output = Utf16Str;
149
150    #[inline]
151    fn get(self, slice: &Utf16Str) -> Option<&Self::Output> {
152        if self.start <= slice.len() { Some(unsafe { self.get_unchecked(slice) }) } else { None }
153    }
154
155    #[inline]
156    fn get_mut(self, slice: &mut Utf16Str) -> Option<&mut Self::Output> {
157        if self.start <= slice.len() { Some(unsafe { self.get_unchecked_mut(slice) }) } else { None }
158    }
159
160    #[inline]
161    unsafe fn get_unchecked(self, slice: &Utf16Str) -> &Self::Output {
162        let ptr = unsafe { slice.as_ptr().add(self.start) };
163        let len = slice.len() - self.start;
164        unsafe { Utf16Str::from_utf16_unchecked(std::slice::from_raw_parts(ptr, len)) }
165    }
166
167    #[inline]
168    unsafe fn get_unchecked_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
169        let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
170        let len = slice.len() - self.start;
171        unsafe { Utf16Str::from_utf16_unchecked_mut(std::slice::from_raw_parts_mut(ptr, len)) }
172    }
173
174    #[inline]
175    fn index(self, slice: &Utf16Str) -> &Self::Output {
176        self.get(slice).expect("slice index out of bounds")
177    }
178
179    #[inline]
180    fn index_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
181        self.get_mut(slice).expect("slice index out of bounds")
182    }
183}
184
185impl SliceIndex<Utf16Str> for RangeInclusive<usize> {
186    type Output = Utf16Str;
187
188    #[inline]
189    fn get(self, slice: &Utf16Str) -> Option<&Self::Output> {
190        if *self.end() == usize::MAX {
191            None
192        } else {
193            (*self.start()..self.end() + 1).get(slice)
194        }
195    }
196
197    #[inline]
198    fn get_mut(self, slice: &mut Utf16Str) -> Option<&mut Self::Output> {
199        if *self.end() == usize::MAX {
200            None
201        } else {
202            (*self.start()..self.end() + 1).get_mut(slice)
203        }
204    }
205
206    #[inline]
207    unsafe fn get_unchecked(self, slice: &Utf16Str) -> &Self::Output {
208        unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
209    }
210
211    #[inline]
212    unsafe fn get_unchecked_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
213        unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
214    }
215
216    #[inline]
217    fn index(self, slice: &Utf16Str) -> &Self::Output {
218        assert!(*self.end() != usize::MAX, "index overflow");
219        (*self.start()..self.end() + 1).index(slice)
220    }
221
222    #[inline]
223    fn index_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
224        assert!(*self.end() != usize::MAX, "index overflow");
225        (*self.start()..self.end() + 1).index_mut(slice)
226    }
227}
228
229impl SliceIndex<Utf16Str> for RangeToInclusive<usize> {
230    type Output = Utf16Str;
231
232    #[inline]
233    fn get(self, slice: &Utf16Str) -> Option<&Self::Output> {
234        if self.end == usize::MAX {
235            None
236        } else {
237            (..self.end + 1).get(slice)
238        }
239    }
240
241    #[inline]
242    fn get_mut(self, slice: &mut Utf16Str) -> Option<&mut Self::Output> {
243        if self.end == usize::MAX {
244            None
245        } else {
246            (..self.end + 1).get_mut(slice)
247        }
248    }
249
250    #[inline]
251    unsafe fn get_unchecked(self, slice: &Utf16Str) -> &Self::Output {
252        unsafe { (..self.end + 1).get_unchecked(slice) }
253    }
254
255    #[inline]
256    unsafe fn get_unchecked_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
257        unsafe { (..self.end + 1).get_unchecked_mut(slice) }
258    }
259
260    #[inline]
261    fn index(self, slice: &Utf16Str) -> &Self::Output {
262        assert!(self.end != usize::MAX, "index overflow");
263        (..self.end + 1).index(slice)
264    }
265
266    #[inline]
267    fn index_mut(self, slice: &mut Utf16Str) -> &mut Self::Output {
268        assert!(self.end != usize::MAX, "index overflow");
269        (..self.end + 1).index_mut(slice)
270    }
271}
272
273impl<I> Index<I> for Utf16Str
274where
275    I: SliceIndex<Utf16Str>
276{
277    type Output = I::Output;
278
279    #[inline]
280    fn index(&self, index: I) -> &I::Output {
281        index.index(self)
282    }
283}
284
285impl<I> IndexMut<I> for Utf16Str
286where
287    I: SliceIndex<Utf16Str>
288{
289    #[inline]
290    fn index_mut(&mut self, index: I) -> &mut I::Output {
291        index.index_mut(self)
292    }
293}
294
295impl<I> Index<I> for Utf16String
296where
297    I: SliceIndex<Utf16Str>
298{
299    type Output = I::Output;
300
301    #[inline]
302    fn index(&self, index: I) -> &I::Output {
303        index.index(self)
304    }
305}
306
307impl<I> IndexMut<I> for Utf16String
308where
309    I: SliceIndex<Utf16Str>
310{
311    #[inline]
312    fn index_mut(&mut self, index: I) -> &mut I::Output {
313        index.index_mut(self)
314    }
315}