use core::marker::PhantomData;
use core::ptr::{null_mut, NonNull};
use munge::munge;
use crate::{u64_le, Chunk, DecodeError, Owned, Slot};
#[repr(C, align(8))]
pub union WirePointer<'buf, T> {
encoded: u64_le,
decoded: *mut T,
_phantom: PhantomData<&'buf mut [Chunk]>,
}
impl<'buf, T> WirePointer<'buf, T> {
pub const fn null() -> Self {
Self { decoded: null_mut() }
}
pub const fn dangling() -> Self {
Self { decoded: NonNull::dangling().as_ptr() }
}
pub fn is_encoded_present(slot: Slot<'_, Self>) -> Result<bool, DecodeError> {
munge!(let Self { encoded } = slot);
match encoded.to_native() {
0 => Ok(false),
u64::MAX => Ok(true),
x => Err(DecodeError::InvalidPointerPresence(x)),
}
}
pub fn encode_present(slot: Slot<'_, Self>) {
munge!(let Self { mut encoded } = slot);
*encoded = u64_le::from_native(u64::MAX);
}
pub fn encode_absent(slot: Slot<'_, Self>) {
munge!(let Self { mut encoded } = slot);
*encoded = u64_le::from_native(0);
}
pub fn set_decoded(slot: Slot<'_, Self>, ptr: Owned<'buf, T>) {
munge!(let Self { mut decoded } = slot);
unsafe { decoded.as_mut_ptr().write(ptr.into_raw()) };
}
pub fn as_ptr(&self) -> *mut T {
unsafe { self.decoded }
}
}