#![no_std]
#![deny(clippy::missing_safety_doc)]
#![deny(missing_docs)]
#![deny(unsafe_op_in_unsafe_fn)]
#[cfg(feature = "alloc")]
extern crate alloc;
mod sealed {
pub trait Sealed {}
}
pub mod array;
pub mod int;
pub mod mem;
pub mod tag;
pub trait IntSliceIndex<T: ?Sized>: int::sealed::SealedSliceIndex<T> {}
pub trait Int: sealed::Sealed {
fn get_int<T>(&self, idx: T) -> Option<&'_ <T as int::sealed::IntSliceIndex<Self>>::Output>
where
T: IntSliceIndex<Self>;
fn get_int_mut<T>(
&mut self,
idx: T,
) -> Option<&'_ mut <T as int::sealed::IntSliceIndex<Self>>::Output>
where
T: IntSliceIndex<Self>;
unsafe fn get_int_unchecked<T>(
&self,
idx: T,
) -> &'_ <T as int::sealed::IntSliceIndex<Self>>::Output
where
T: IntSliceIndex<Self>;
unsafe fn get_int_unchecked_mut<T>(
&mut self,
idx: T,
) -> &'_ mut <T as int::sealed::IntSliceIndex<Self>>::Output
where
T: IntSliceIndex<Self>;
}
impl<U> sealed::Sealed for [U] {}
impl<U> Int for [U] {
fn get_int<T>(&self, idx: T) -> Option<&'_ <T as int::sealed::IntSliceIndex<Self>>::Output>
where
T: IntSliceIndex<Self>,
{
<T as int::sealed::IntSliceIndex<Self>>::get(idx, self)
}
fn get_int_mut<T>(
&mut self,
idx: T,
) -> Option<&'_ mut <T as int::sealed::IntSliceIndex<Self>>::Output>
where
T: IntSliceIndex<Self>,
{
<T as int::sealed::IntSliceIndex<Self>>::get_mut(idx, self)
}
unsafe fn get_int_unchecked<T>(
&self,
idx: T,
) -> &'_ <T as int::sealed::IntSliceIndex<Self>>::Output
where
T: IntSliceIndex<Self>,
{
unsafe { <T as int::sealed::IntSliceIndex<Self>>::get_unchecked(idx, self) }
}
unsafe fn get_int_unchecked_mut<T>(
&mut self,
idx: T,
) -> &'_ mut <T as int::sealed::IntSliceIndex<Self>>::Output
where
T: IntSliceIndex<Self>,
{
unsafe { <T as int::sealed::IntSliceIndex<Self>>::get_unchecked_mut(idx, self) }
}
}
impl sealed::Sealed for str {}
impl Int for str {
fn get_int<T>(&self, idx: T) -> Option<&'_ <T as int::sealed::IntSliceIndex<Self>>::Output>
where
T: IntSliceIndex<Self>,
{
<T as int::sealed::IntSliceIndex<Self>>::get(idx, self)
}
fn get_int_mut<T>(
&mut self,
idx: T,
) -> Option<&'_ mut <T as int::sealed::IntSliceIndex<Self>>::Output>
where
T: IntSliceIndex<Self>,
{
<T as int::sealed::IntSliceIndex<Self>>::get_mut(idx, self)
}
unsafe fn get_int_unchecked<T>(
&self,
idx: T,
) -> &'_ <T as int::sealed::IntSliceIndex<Self>>::Output
where
T: IntSliceIndex<Self>,
{
unsafe { <T as int::sealed::IntSliceIndex<Self>>::get_unchecked(idx, self) }
}
unsafe fn get_int_unchecked_mut<T>(
&mut self,
idx: T,
) -> &'_ mut <T as int::sealed::IntSliceIndex<Self>>::Output
where
T: IntSliceIndex<Self>,
{
unsafe { <T as int::sealed::IntSliceIndex<Self>>::get_unchecked_mut(idx, self) }
}
}
#[allow(non_snake_case)]
pub fn Int<T>(idx: T) -> int::Int<T> {
int::Int(idx)
}
macro_rules! doctest_readme {
{ $content:expr } => {
#[doc = $content] extern {}
}
}
doctest_readme!(include_str!("../Readme.md"));
#[cfg(test)]
mod test {
use super::Int;
#[test]
#[should_panic = "100"]
fn panics_with_length_u32() {
[0u8; 0][Int(100u32)];
}
#[test]
#[should_panic = "100"]
fn panics_with_length_u8() {
[0u8; 0][Int(100u8)];
}
#[test]
#[should_panic = "-1"]
fn panics_with_length_i8() {
[0u8; 0][Int(-1i8)];
}
#[test]
#[should_panic = "100000000000000000000000000000000000000"]
fn panics_with_length_u128() {
[0u8; 0][Int(100_000_000_000_000_000_000_000_000_000_000_000_000u128)];
}
#[test]
fn index_with_all() {
let slice = [0u8; 10];
macro_rules! assert_slice_success {
(@$slice:path, $exp:expr) => {
assert!($slice.get_int($exp).is_some());
};
($slice:path: $($exp:expr),*) => {
$(assert_slice_success!(@$slice, $exp);)*
}
}
macro_rules! assert_slice_fail {
(@$slice:path, $exp:expr) => {
assert_eq!($slice.get_int($exp), None);
};
($slice:path: $($exp:expr),*) => {
$(assert_slice_fail!(@$slice, $exp);)*
}
}
assert_slice_success!(slice: 0u8, 0i8, 0u16, 0i16, 0u32, 0i32, 0u64, 0i64);
assert_slice_success!(slice: ..10u8, ..10i8, ..10u16, ..10i16, ..10u32, ..10i32, ..10u64, ..10i64);
assert_slice_success!(slice: 0..10u8, 0..10i8, 0..10u16, 0..10i16, 0..10u32, 0..10i32, 0..10u64, 0..10i64);
assert_slice_success!(slice: 10u8.., 10i8.., 10u16.., 10i16.., 10u32.., 10i32.., 10u64.., 10i64..);
assert_slice_fail!(slice: -1i8, -1i16, -1i32, -1i64);
}
#[test]
fn unchecked() {
let mut slice = [0u8, 1, 2, 3];
macro_rules! assert_slice_eq {
(@$slice:path, $idx:expr, $exp:expr) => {
assert_eq!($slice[Int($idx)], $exp);
assert_eq!(&mut $slice[Int($idx)], $exp);
unsafe {
assert_eq!($slice.get_int_unchecked($idx), $exp);
assert_eq!($slice.get_int_unchecked_mut($idx), $exp);
}
};
($slice:path[idx], $result:expr, for idx in [$($idx:expr),*]) => {
$(assert_slice_eq!(@$slice, $idx, $result);)*
}
}
assert_slice_eq!(slice[idx], [1, 2],
for idx in [1u8..3, 1i8..3, 1u16..3, 1i16..3, 1u32..3, 1i32..3, 1u64..3, 1i64..3]);
}
#[test]
fn str_indices() {
let text = "What if ascii still has it?";
assert_eq!(text.get_int(8u8..13), Some("ascii"));
}
}