use core::fmt;
use core::mem::{size_of, ManuallyDrop};
use core::slice;
use crate::buf::BufMut;
use crate::pointer::Pointee;
use crate::traits::ZeroCopy;
#[repr(C, packed)]
pub union MaybeUninit<T> {
uninit: (),
value: ManuallyDrop<T>,
}
impl<T> MaybeUninit<T> {
pub const fn uninit() -> Self {
MaybeUninit { uninit: () }
}
#[inline]
pub fn write(&mut self, value: &T) -> &mut [u8]
where
T: ZeroCopy,
{
unsafe {
let ptr = self as *mut Self as *mut u8;
BufMut::new(ptr).store_unaligned(value);
slice::from_raw_parts_mut(ptr, size_of::<T>())
}
}
}
impl<T> fmt::Debug for MaybeUninit<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MaybeUninit").finish_non_exhaustive()
}
}
impl<T, O> Pointee<O> for MaybeUninit<T>
where
T: Pointee<O>,
{
type Metadata = T::Metadata;
type Packed = T::Packed;
}