Trait SubsliceToArrayRef

Source
pub trait SubsliceToArrayRef<T, const N: usize> {
    // Required method
    fn subslice_to_array_ref<const START: usize, const END: usize>(
        &self,
    ) -> &[T; N];
}
Expand description

Conversion from a subslice to a reference to an array, with compile-time checks on the START..END range used to index into a source slice.

Required Methods§

Source

fn subslice_to_array_ref<const START: usize, const END: usize>(&self) -> &[T; N]

Compile-time checked version of code like slice[START..END].try_into().unwrap() for converting part of a slice into a reference to an array of length N.

The function confirms at compile time that START <= END and N == END - START. A compile-time error is thrown if this requirement is not met.

This internally uses subslice_to_array_ref; if you need to explicitly set the T or N generics, you should directly use subslice_to_array_ref, but in most cases this wrapper is more convenient.

§Panics

Panics if any index in the START..END range is out-of-bounds for the provided slice. We cannot check that at compile time.

§Examples
use subslice_to_array::SubsliceToArrayRef as _;
let data: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(
    data.subslice_to_array_ref::<0, 4>(),
    &[0, 1, 2, 3],
);
assert_eq!(
    data.subslice_to_array_ref::<4, 9>(),
    &[4, 5, 6, 7, 8],
);

fn fn_that_only_gets_a_slice(bytes: &[u8]) -> Option<&[u8; 4]> {
    if bytes.len() < 5 {
        None
    } else {
        Some(bytes.subslice_to_array_ref::<1, 5>())
    }
}

assert_eq!(
    fn_that_only_gets_a_slice(data),
    Some(&[1, 2, 3, 4]),
);

let data_vec: Vec<u8> = vec![4, 2];
let data_arr: &[u8; 2] = data_vec.subslice_to_array_ref::<0, 2>();
assert_eq!(data_arr, &[4, 2]);

// This is a pretty absurd edge case, but it works.
let unit_arr: [(); usize::MAX] = [(); usize::MAX];
let unit_slice: &[()] = unit_arr.as_slice();
let unit_arr_ref: &[(); usize::MAX] = unit_slice.subslice_to_array_ref::<0, {usize::MAX}>();
§Compile fail examples

If END - START were computed in release mode without checking that START <= END, the below computation would wrap around to 2. Since we do perform that check, this fails to compile.

use subslice_to_array::SubsliceToArrayRef as _;
let data: &[u32] = &[0];
let data_2: &[u32; 2] = data.subslice_to_array_ref::<{usize::MAX}, 1>();

Below, END - START is not equal to N.

use subslice_to_array::SubsliceToArrayRef as _;
let data: &[u32] = &[0, 1, 2];
let data_3: &[u32; 3] = data.subslice_to_array_ref::<1, 3>();

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<T, const N: usize> SubsliceToArrayRef<T, N> for [T]

Source§

fn subslice_to_array_ref<const START: usize, const END: usize>(&self) -> &[T; N]

Implementors§