use core::slice::SliceIndex;
use crate::{slice_utf8::slice_error_fail, string_base::StringBase};
unsafe impl SliceIndex<StringBase<[u8]>> for core::ops::RangeFull {
type Output = StringBase<[u8]>;
#[inline]
fn get(self, slice: &StringBase<[u8]>) -> Option<&Self::Output> {
Some(slice)
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[u8]>) -> Option<&mut Self::Output> {
Some(slice)
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[u8]>) -> *const Self::Output {
slice
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[u8]>) -> *mut Self::Output {
slice
}
#[inline]
fn index(self, slice: &StringBase<[u8]>) -> &Self::Output {
slice
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[u8]>) -> &mut Self::Output {
slice
}
}
unsafe impl SliceIndex<StringBase<[u8]>> for core::ops::Range<usize> {
type Output = StringBase<[u8]>;
#[inline]
fn get(self, slice: &StringBase<[u8]>) -> Option<&Self::Output> {
if self.start <= self.end
&& slice.is_char_boundary(self.start)
&& slice.is_char_boundary(self.end)
{
Some(unsafe { &*self.get_unchecked(slice) })
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[u8]>) -> Option<&mut Self::Output> {
if self.start <= self.end
&& slice.is_char_boundary(self.start)
&& slice.is_char_boundary(self.end)
{
Some(unsafe { &mut *self.get_unchecked_mut(slice) })
} else {
None
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[u8]>) -> *const Self::Output {
let slice = slice as *const [u8];
let ptr = slice.as_ptr().add(self.start);
let len = self.end - self.start;
core::ptr::slice_from_raw_parts(ptr, len) as *const StringBase<[u8]>
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[u8]>) -> *mut Self::Output {
let slice = slice as *mut [u8];
let ptr = slice.as_mut_ptr().add(self.start);
let len = self.end - self.start;
core::ptr::slice_from_raw_parts_mut(ptr, len) as *mut StringBase<[u8]>
}
#[inline]
fn index(self, slice: &StringBase<[u8]>) -> &Self::Output {
let (start, end) = (self.start, self.end);
match self.get(slice) {
Some(s) => s,
None => slice_error_fail(slice, start, end),
}
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[u8]>) -> &mut Self::Output {
if self.start <= self.end
&& slice.is_char_boundary(self.start)
&& slice.is_char_boundary(self.end)
{
unsafe { &mut *self.get_unchecked_mut(slice) }
} else {
slice_error_fail(slice, self.start, self.end)
}
}
}
unsafe impl SliceIndex<StringBase<[u8]>> for core::ops::RangeTo<usize> {
type Output = StringBase<[u8]>;
#[inline]
fn get(self, slice: &StringBase<[u8]>) -> Option<&Self::Output> {
if slice.is_char_boundary(self.end) {
Some(unsafe { &*self.get_unchecked(slice) })
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[u8]>) -> Option<&mut Self::Output> {
if slice.is_char_boundary(self.end) {
Some(unsafe { &mut *self.get_unchecked_mut(slice) })
} else {
None
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[u8]>) -> *const Self::Output {
let slice = slice as *const [u8];
let ptr = slice.as_ptr();
core::ptr::slice_from_raw_parts(ptr, self.end) as *const StringBase<[u8]>
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[u8]>) -> *mut Self::Output {
let slice = slice as *mut [u8];
let ptr = slice.as_mut_ptr();
core::ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut StringBase<[u8]>
}
#[inline]
fn index(self, slice: &StringBase<[u8]>) -> &Self::Output {
let end = self.end;
match self.get(slice) {
Some(s) => s,
None => slice_error_fail(slice, 0, end),
}
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[u8]>) -> &mut Self::Output {
if slice.is_char_boundary(self.end) {
unsafe { &mut *self.get_unchecked_mut(slice) }
} else {
slice_error_fail(slice, 0, self.end)
}
}
}
unsafe impl SliceIndex<StringBase<[u8]>> for core::ops::RangeFrom<usize> {
type Output = StringBase<[u8]>;
#[inline]
fn get(self, slice: &StringBase<[u8]>) -> Option<&Self::Output> {
if slice.is_char_boundary(self.start) {
Some(unsafe { &*self.get_unchecked(slice) })
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[u8]>) -> Option<&mut Self::Output> {
if slice.is_char_boundary(self.start) {
Some(unsafe { &mut *self.get_unchecked_mut(slice) })
} else {
None
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[u8]>) -> *const Self::Output {
let slice = slice as *const [u8];
let ptr = slice.as_ptr().add(self.start);
let len = slice.len() - self.start;
core::ptr::slice_from_raw_parts(ptr, len) as *const StringBase<[u8]>
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[u8]>) -> *mut Self::Output {
let slice = slice as *mut [u8];
let ptr = slice.as_mut_ptr().add(self.start);
let len = slice.len() - self.start;
core::ptr::slice_from_raw_parts_mut(ptr, len) as *mut StringBase<[u8]>
}
#[inline]
fn index(self, slice: &StringBase<[u8]>) -> &Self::Output {
let (start, end) = (self.start, slice.len());
match self.get(slice) {
Some(s) => s,
None => slice_error_fail(slice, start, end),
}
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[u8]>) -> &mut Self::Output {
if slice.is_char_boundary(self.start) {
unsafe { &mut *self.get_unchecked_mut(slice) }
} else {
slice_error_fail(slice, self.start, slice.len())
}
}
}
unsafe impl SliceIndex<StringBase<[u8]>> for core::ops::RangeToInclusive<usize> {
type Output = StringBase<[u8]>;
#[inline]
fn get(self, slice: &StringBase<[u8]>) -> Option<&Self::Output> {
if self.end == usize::MAX {
None
} else {
(..self.end + 1).get(slice)
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[u8]>) -> Option<&mut Self::Output> {
if self.end == usize::MAX {
None
} else {
(..self.end + 1).get_mut(slice)
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[u8]>) -> *const Self::Output {
(..self.end + 1).get_unchecked(slice)
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[u8]>) -> *mut Self::Output {
(..self.end + 1).get_unchecked_mut(slice)
}
#[inline]
fn index(self, slice: &StringBase<[u8]>) -> &Self::Output {
if self.end == usize::MAX {
str_index_overflow_fail();
}
(..self.end + 1).index(slice)
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[u8]>) -> &mut Self::Output {
if self.end == usize::MAX {
str_index_overflow_fail();
}
(..self.end + 1).index_mut(slice)
}
}
#[inline(never)]
#[cold]
#[track_caller]
fn str_index_overflow_fail() -> ! {
panic!("attempted to index str up to maximum usize");
}