use std::{
ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive},
slice::SliceIndex,
};
pub trait SliceRange: SliceIndex<[u8], Output = [u8]> + Clone + RangeBounds<usize> {}
impl<T: SliceIndex<[u8], Output = [u8]> + Clone + RangeBounds<usize>> SliceRange for T {}
pub(crate) trait IndexAdjustable {
#[must_use]
fn add(&self, n: usize) -> Self;
#[must_use]
#[allow(dead_code)]
fn sub(&self, n: usize) -> Self;
#[must_use]
#[allow(dead_code)]
fn saturating_sub(&self, n: usize) -> Self;
}
impl IndexAdjustable for usize {
#[inline]
fn add(&self, n: usize) -> Self {
self + n
}
#[inline]
fn sub(&self, n: usize) -> Self {
self - n
}
#[inline]
fn saturating_sub(&self, n: usize) -> Self {
usize::saturating_sub(*self, n)
}
}
impl IndexAdjustable for Range<usize> {
#[inline]
fn add(&self, n: usize) -> Self {
self.start + n..self.end + n
}
#[inline]
fn sub(&self, n: usize) -> Self {
self.start - n..self.end - n
}
#[inline]
fn saturating_sub(&self, n: usize) -> Self {
self.start.saturating_sub(n)..self.end.saturating_sub(n)
}
}
impl IndexAdjustable for RangeInclusive<usize> {
#[inline]
fn add(&self, n: usize) -> Self {
self.start() + n..=self.end() + n
}
#[inline]
fn sub(&self, n: usize) -> Self {
self.start() - n..=self.end() - n
}
#[inline]
fn saturating_sub(&self, n: usize) -> Self {
self.start().saturating_sub(n)..=self.end().saturating_sub(n)
}
}
impl IndexAdjustable for RangeFrom<usize> {
#[inline]
fn add(&self, n: usize) -> Self {
self.start + n..
}
#[inline]
fn sub(&self, n: usize) -> Self {
self.start - n..
}
#[inline]
fn saturating_sub(&self, n: usize) -> Self {
self.start.saturating_sub(n)..
}
}
impl IndexAdjustable for RangeTo<usize> {
#[inline]
fn add(&self, n: usize) -> Self {
..self.end + n
}
#[inline]
fn sub(&self, n: usize) -> Self {
..self.end - n
}
#[inline]
fn saturating_sub(&self, n: usize) -> Self {
..self.end.saturating_sub(n)
}
}
impl IndexAdjustable for RangeToInclusive<usize> {
#[inline]
fn add(&self, n: usize) -> Self {
..=self.end + n
}
#[inline]
fn sub(&self, n: usize) -> Self {
..=self.end - n
}
#[inline]
fn saturating_sub(&self, n: usize) -> Self {
..=self.end.saturating_sub(n)
}
}