use std::{
io,
mem::{size_of, MaybeUninit},
slice::{from_raw_parts, from_raw_parts_mut},
};
pub unsafe trait DataInit: Copy + Send + Sync {
fn from_slice(data: &[u8]) -> Option<&Self> {
if data.len() != size_of::<Self>() {
return None;
}
match unsafe { data.align_to::<Self>() } {
([], [mid], []) => Some(mid),
_ => None,
}
}
fn read_from_prefix(data: &[u8]) -> Option<Self> {
data.get(0..size_of::<Self>())
.and_then(|slice| Self::from_slice(slice))
.copied()
}
fn from_mut_slice(data: &mut [u8]) -> Option<&mut Self> {
if data.len() != size_of::<Self>() {
return None;
}
match unsafe { data.align_to_mut::<Self>() } {
([], [mid], []) => Some(mid),
_ => None,
}
}
fn from_reader<R: io::Read>(mut read: R) -> io::Result<Self> {
let mut out = MaybeUninit::zeroed();
let buf = unsafe { from_raw_parts_mut(out.as_mut_ptr() as *mut u8, size_of::<Self>()) };
read.read_exact(buf)?;
Ok(unsafe { out.assume_init() })
}
fn as_slice(&self) -> &[u8] {
unsafe { from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
}
fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { from_raw_parts_mut(self as *mut Self as *mut u8, size_of::<Self>()) }
}
}