use std::mem::size_of;
use std::mem::MaybeUninit;
use std::slice;
pub(crate) trait Bytes
where
Self: Sized + 'static,
{
#[inline]
fn as_byte_mut_ptr(&mut self) -> *mut MaybeUninit<u8> {
self as *mut Self as *mut MaybeUninit<u8>
}
#[inline]
fn as_byte_ptr(&self) -> *const MaybeUninit<u8> {
self as *const Self as *const MaybeUninit<u8>
}
#[inline]
unsafe fn from_byte_mut_ptr<'a>(bytes: *mut MaybeUninit<u8>) -> &'a mut Self {
&mut *(bytes as *mut Self)
}
#[inline]
unsafe fn from_byte_ptr<'a>(bytes: *const MaybeUninit<u8>) -> &'a Self {
&*(bytes as *const Self)
}
#[inline]
fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
unsafe { slice::from_raw_parts_mut(self.as_byte_mut_ptr(), size_of::<Self>()) }
}
#[inline]
fn as_bytes(&self) -> &[MaybeUninit<u8>] {
unsafe { slice::from_raw_parts(self.as_byte_ptr(), size_of::<Self>()) }
}
#[inline]
unsafe fn from_bytes_mut(bytes: &mut [MaybeUninit<u8>]) -> &mut Self {
assert_eq!(bytes.len(), size_of::<Self>());
Self::from_byte_mut_ptr(bytes.as_mut_ptr())
}
#[inline]
unsafe fn from_bytes(bytes: &[MaybeUninit<u8>]) -> &Self {
assert_eq!(bytes.len(), size_of::<Self>());
Self::from_byte_ptr(bytes.as_ptr())
}
#[inline]
fn box_into_box_bytes(b: Box<Self>) -> Box<[MaybeUninit<u8>]> {
let byte_ptr = Box::into_raw(b) as *mut MaybeUninit<u8>;
unsafe { Box::from_raw(slice::from_raw_parts_mut(byte_ptr, size_of::<Self>())) }
}
#[inline]
unsafe fn box_from_box_bytes(b: Box<[MaybeUninit<u8>]>) -> Box<Self> {
Box::from_raw(Box::into_raw(b) as *mut Self)
}
#[inline]
fn try_into_usize(&self) -> Option<MaybeUninit<usize>> {
unsafe {
if size_of::<Self>() == size_of::<MaybeUninit<usize>>() {
Some(std::mem::transmute_copy(self))
} else {
None
}
}
}
#[inline]
unsafe fn try_from_usize(b: MaybeUninit<usize>) -> Option<Self> {
if size_of::<Self>() == size_of::<MaybeUninit<usize>>() {
Some(std::mem::transmute_copy(&b))
} else {
None
}
}
}
impl<T> Bytes for T where T: 'static {}