use core::fmt;
use core::mem::{size_of, ManuallyDrop};
use core::ptr::NonNull;
use core::slice;
use crate::buf;
use crate::pointer::{Pointee, Size};
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 = NonNull::new_unchecked(self as *mut Self as *mut u8);
buf::store_unaligned(ptr, value);
slice::from_raw_parts_mut(ptr.as_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> Pointee for MaybeUninit<T>
where
T: Pointee,
{
type Metadata = T::Metadata;
type Stored<O> = T::Stored<O>
where
O: Size;
#[inline]
fn try_from_metadata<O>(metadata: Self::Metadata) -> Option<Self::Stored<O>>
where
O: Size,
{
T::try_from_metadata(metadata)
}
}