Skip to main content

SubsliceToArrayMut

Trait SubsliceToArrayMut 

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

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

Required Methods§

Source

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

Compile-time checked version of code like (&mut slice[START..END]).try_into().unwrap() for converting part of a mutable slice into a mutable 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_mut; if you need to explicitly set the T or N generics, you should directly use subslice_to_array_mut, 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::SubsliceToArrayMut as _;
let data: &mut [u8] = &mut [0, 1, 2, 3, 4];
*data.subslice_to_array_mut::<1, 3>() = 0xffff_u16.to_le_bytes();
assert_eq!(
    data,
    &mut [0, 255, 255, 3, 4],
);

let data: &mut [u8] = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(
    data.subslice_to_array_mut::<0, 4>(),
    &mut [0, 1, 2, 3],
);
assert_eq!(
    data.subslice_to_array_mut::<4, 9>(),
    &mut [4, 5, 6, 7, 8],
);

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

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

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

// This is a pretty absurd edge case, but it works.
let mut unit_arr: [(); usize::MAX] = [(); usize::MAX];
let unit_slice: &mut [()] = unit_arr.as_mut_slice();
let unit_arr_ref: &mut [(); usize::MAX] = unit_slice
    .subslice_to_array_mut::<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::SubsliceToArrayMut as _;
let data: &[u32] = &[0];
let data_2: &[u32; 2] = data.subslice_to_array_mut::<{usize::MAX}, 1>();

Below, END - START is not equal to N.

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

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

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

Source§

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

Implementors§