use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
use super::algorithm::safe_index;
pub trait RyleySliceIndex<T: ?Sized> {
type Output: ?Sized;
fn index(self, slice: &T) -> &Self::Output;
fn index_mut(self, slice: &mut T) -> &mut Self::Output;
}
impl<T> RyleySliceIndex<[T]> for isize {
type Output = T;
fn index(self, slice: &[T]) -> &Self::Output {
&slice[safe_index(self, slice.len())]
}
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
let len=slice.len();
&mut slice[safe_index(self, len)]
}
}
impl<T> RyleySliceIndex<[T]> for Range<isize> {
type Output = [T];
fn index(self, mut slice: &[T]) -> &Self::Output {
let len=slice.len();
let mut idx=safe_index(self.end,len+1);
if self.end<0 || self.end.unsigned_abs()!=idx {idx-=1;}
slice=slice.split_at(idx).0;
slice=slice.split_at(safe_index(self.start,len)).1;
slice
}
fn index_mut(self, mut slice: &mut [T]) -> &mut Self::Output {
let len=slice.len();
let mut idx=safe_index(self.end,len+1);
if self.end<0 || self.end.unsigned_abs()!=idx {idx-=1;}
slice=slice.split_at_mut(idx).0;
slice=slice.split_at_mut(safe_index(self.start,len)).1;
slice
}
}
impl<T> RyleySliceIndex<[T]> for RangeTo<isize> {
type Output = [T];
fn index(self, mut slice: &[T]) -> &Self::Output {
let mut index=safe_index(self.end, slice.len()+1);
if self.end<0 || index!=self.end.unsigned_abs() {index-=1;}
slice=slice.split_at(index).0;
slice
}
fn index_mut(self, mut slice: &mut [T]) -> &mut Self::Output {
let mut index=safe_index(self.end, slice.len()+1);
if self.end<0 || index!=self.end.unsigned_abs() {index-=1;}
slice=slice.split_at_mut(index).0;
slice
}
}
impl<T> RyleySliceIndex<[T]> for RangeFrom<isize> {
type Output = [T];
fn index(self, mut slice: &[T]) -> &Self::Output {
let mut index=safe_index(self.start, slice.len()+1);
if self.start<0 || index!=self.start.unsigned_abs() {index-=1;}
slice=slice.split_at(index).1;
slice
}
fn index_mut(self, mut slice: &mut [T]) -> &mut Self::Output {
let mut index=safe_index(self.start, slice.len()+1);
if self.start<0 || index!=self.start.unsigned_abs() {index-=1;}
slice=slice.split_at_mut(index).1;
slice
}
}
impl<T> RyleySliceIndex<[T]> for RangeFull {
type Output = [T];
fn index(self, slice: &[T]) -> &Self::Output {
slice
}
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
slice
}
}
impl<T> RyleySliceIndex<[T]> for RangeInclusive<isize> {
type Output = [T];
fn index(self, mut slice: &[T]) -> &Self::Output {
let len=slice.len();
let mut idx=safe_index(*self.end(),len+1);
if *self.end()>=0 && idx==self.end().unsigned_abs() {idx+=1;}
slice=slice.split_at(idx).0;
slice=slice.split_at(safe_index(*self.start(),len)).1;
slice
}
fn index_mut(self, mut slice: &mut [T]) -> &mut Self::Output {
let len=slice.len();
let mut idx=safe_index(*self.end(),len+1);
if *self.end()>=0 && idx==self.end().unsigned_abs() {idx+=1;}
slice=slice.split_at_mut(idx).0;
slice=slice.split_at_mut(safe_index(*self.start(),len)).1;
slice
}
}
impl<T> RyleySliceIndex<[T]> for RangeToInclusive<isize> {
type Output = [T];
fn index(self, mut slice: &[T]) -> &Self::Output {
let mut index=safe_index(self.end, slice.len()+1);
if self.end>=0 && index==self.end.unsigned_abs() {index+=1;}
slice=slice.split_at(index).0;
slice
}
fn index_mut(self, mut slice: &mut [T]) -> &mut Self::Output {
let mut index=safe_index(self.end, slice.len()+1);
if self.end>=0 && index==self.end.unsigned_abs() {index+=1;}
slice=slice.split_at_mut(index).0;
slice
}
}