Trait SubsliceToArray

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

Conversion from a subslice with copyable data 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<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 an array of length N.

This is only implemented for slices &[T] where T is Copy.

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; if you need to explicitly set the T or N generics, you should directly use subslice_to_array, 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::SubsliceToArray as _;
let data: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(
    data.subslice_to_array::<0, 4>(),
    [0, 1, 2, 3],
);
assert_eq!(
    data.subslice_to_array::<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::<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::<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 round_trip: [(); usize::MAX] = unit_slice.subslice_to_array::<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::SubsliceToArray as _;
let data: &[u32] = &[0];
let data_2: [u32; 2] = data.subslice_to_array::<{usize::MAX}, 1>();

Below, END - START is not equal to N.

use subslice_to_array::SubsliceToArray as _;
let data: &[u32] = &[0, 1, 2];
let data_3: [u32; 3] = data.subslice_to_array::<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: Copy, const N: usize> SubsliceToArray<T, N> for [T]

Source§

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

Implementors§