use super::length::Length;
use std::ops::Range;
pub(crate) trait Slice<Output: ?Sized>: TryIndexRange<Output> + Length {}
impl<S, O> Slice<O> for S
where
S: TryIndexRange<O> + Length + ?Sized,
O: ?Sized,
{
}
pub(crate) trait TryIndexRange<Output: ?Sized> {
fn try_index(&self, index: Range<usize>) -> Option<&Output>;
fn index(&self, index: Range<usize>) -> &Output {
self.try_index(index.clone())
.unwrap_or_else(|| panic!("index {index:?} is invalid"))
}
unsafe fn index_unchecked(&self, index: Range<usize>) -> &Output;
}
impl<T> TryIndexRange<[T]> for [T] {
fn try_index(&self, index: Range<usize>) -> Option<&[T]> {
self.get(index)
}
fn index(&self, index: Range<usize>) -> &[T] {
&self[index]
}
unsafe fn index_unchecked(&self, index: Range<usize>) -> &[T] {
self.get_unchecked(index)
}
}
impl TryIndexRange<str> for [u8] {
fn try_index(&self, index: Range<usize>) -> Option<&str> {
std::str::from_utf8(self.get(index)?).ok()
}
unsafe fn index_unchecked(&self, index: Range<usize>) -> &str {
std::str::from_utf8_unchecked(self.get_unchecked(index))
}
}
impl TryIndexRange<[u8]> for str {
fn try_index(&self, index: Range<usize>) -> Option<&[u8]> {
self.as_bytes().get(index)
}
fn index(&self, index: Range<usize>) -> &[u8] {
&self.as_bytes()[index]
}
unsafe fn index_unchecked(&self, index: Range<usize>) -> &[u8] {
self.as_bytes().get_unchecked(index)
}
}
impl TryIndexRange<str> for str {
fn try_index(&self, index: Range<usize>) -> Option<&str> {
self.get(index)
}
fn index(&self, index: Range<usize>) -> &str {
&self[index]
}
unsafe fn index_unchecked(&self, index: Range<usize>) -> &str {
self.get_unchecked(index)
}
}