ryley 0.1.1

Syntax unifies programmers
Documentation
//! `ryley_slice_index` contains a custom trait for indices used inside ryley
use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};

use super::algorithm::safe_index;

/// A helper trait used for indexing operations
pub trait RyleySliceIndex<T: ?Sized> {
    /// Output type of index operation
    type Output: ?Sized;
    /// Performs the indexing (container[index]) operation
    fn index(self, slice: &T) -> &Self::Output;
    /// Performs the mutable indexing (container[index]) operation
    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
    }
}