use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CastError {
NotMultiple,
Misaligned,
}
impl fmt::Display for CastError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotMultiple => write!(
f,
"byte slice length is not a multiple of the target type size. Fix: align the buffer size to the element size."
),
Self::Misaligned => write!(
f,
"byte slice alignment does not match the target type alignment. Fix: use an aligned buffer or copy to an aligned Vec."
),
}
}
}
impl std::error::Error for CastError {}
pub fn safe_cast_slice<T: bytemuck::Pod>(bytes: &[u8]) -> Result<&[T], CastError> {
let size = core::mem::size_of::<T>();
if size == 0 {
return Ok(bytemuck::cast_slice(bytes));
}
if bytes.len() % size != 0 {
return Err(CastError::NotMultiple);
}
if bytes.as_ptr().align_offset(core::mem::align_of::<T>()) != 0 {
return Err(CastError::Misaligned);
}
Ok(bytemuck::cast_slice(bytes))
}
#[must_use]
pub fn safe_bytes_of_slice<T: bytemuck::Pod>(values: &[T]) -> &[u8] {
bytemuck::cast_slice(values)
}