#![allow(dead_code, clippy::let_unit_value)]
use core::mem::MaybeUninit;
pub(crate) fn split_array_ref<
const L: usize,
const R: usize,
const N: usize,
>(
xs: &[u8; N],
) -> (&[u8; L], &[u8; R]) {
let () = AssertEqSum::<L, R, N>::OK;
let (left, right) = xs.split_at(L);
(left.try_into().unwrap(), right.try_into().unwrap())
}
pub(crate) fn split_array_mut<
const L: usize,
const R: usize,
const N: usize,
>(
xs: &mut [u8; N],
) -> (&mut [u8; L], &mut [u8; R]) {
let () = AssertEqSum::<L, R, N>::OK;
let (left, right) = xs.split_at_mut(L);
(left.try_into().unwrap(), right.try_into().unwrap())
}
pub(crate) fn as_chunks<const N: usize, T>(slice: &[T]) -> (&[[T; N]], &[T]) {
let () = AssertNonZero::<N>::OK;
let len = slice.len() / N;
let (head, tail) = slice.split_at(len * N);
let head = unsafe { std::slice::from_raw_parts(head.as_ptr().cast(), len) };
(head, tail)
}
pub(crate) fn as_chunks_mut<const N: usize, T>(
slice: &mut [T],
) -> (&mut [[T; N]], &mut [T]) {
let () = AssertNonZero::<N>::OK;
let len = slice.len() / N;
let (head, tail) = slice.split_at_mut(len * N);
let head = unsafe {
std::slice::from_raw_parts_mut(head.as_mut_ptr().cast(), len)
};
(head, tail)
}
fn split_at_checked<T>(slice: &[T], mid: usize) -> Option<(&[T], &[T])> {
(mid <= slice.len()).then(|| slice.split_at(mid))
}
fn split_at_mut_checked<T>(
slice: &mut [T],
mid: usize,
) -> Option<(&mut [T], &mut [T])> {
(mid <= slice.len()).then(|| slice.split_at_mut(mid))
}
pub(crate) fn split_at<const L: usize, T>(xs: &[T]) -> Option<(&[T; L], &[T])> {
split_at_checked(xs, L).map(|(head, tail)| (head.try_into().unwrap(), tail))
}
pub(crate) fn split_at_mut<const L: usize, T>(
xs: &mut [T],
) -> Option<(&mut [T; L], &mut [T])> {
split_at_mut_checked(xs, L)
.map(|(head, tail)| (head.try_into().unwrap(), tail))
}
struct AssertEqSum<const A: usize, const B: usize, const S: usize>;
impl<const A: usize, const B: usize, const S: usize> AssertEqSum<A, B, S> {
const OK: () = assert!(S == A + B);
}
struct AssertNonZero<const N: usize>;
impl<const N: usize> AssertNonZero<N> {
const OK: () = assert!(N != 0);
}
pub(crate) fn write_slice(dst: &mut [MaybeUninit<u8>], src: &[u8]) {
let src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(src) };
dst.copy_from_slice(src);
}