use core::{fmt, marker::PhantomData, mem::MaybeUninit};
#[allow(missing_docs)]
#[repr(C)]
#[derive(Copy, Clone)]
pub union RawValue {
pub i32: i32,
pub i64: i64,
pub u32: u32,
pub u64: u64,
pub f32: f32,
pub f64: f64,
pub i128: i128,
pub u128: u128,
pub funcref: usize,
pub externref: usize,
pub bytes: [u8; 16],
}
impl From<i32> for RawValue {
fn from(value: i32) -> Self {
Self { i32: value }
}
}
impl From<i64> for RawValue {
fn from(value: i64) -> Self {
Self { i64: value }
}
}
impl From<f32> for RawValue {
fn from(value: f32) -> Self {
Self { f32: value }
}
}
impl From<f64> for RawValue {
fn from(value: f64) -> Self {
Self { f64: value }
}
}
impl Default for RawValue {
fn default() -> Self {
Self { bytes: [0; 16] }
}
}
impl fmt::Debug for RawValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawValue")
.field("bytes", unsafe { &self.bytes })
.finish()
}
}
macro_rules! partial_eq {
($($t:ty => $f:tt),*) => ($(
impl PartialEq<$t> for RawValue {
fn eq(&self, o: &$t) -> bool {
unsafe { self.$f == *o }
}
}
)*)
}
partial_eq! {
i32 => i32,
u32 => u32,
i64 => i64,
u64 => u64,
f32 => f32,
f64 => f64,
i128 => i128,
u128 => u128
}
impl PartialEq for RawValue {
fn eq(&self, o: &Self) -> bool {
unsafe { self.u128 == o.u128 }
}
}
pub unsafe trait ValueType: Copy {
fn zero_padding_bytes(&self, bytes: &mut [MaybeUninit<u8>]);
}
macro_rules! primitives {
($($t:ident)*) => ($(
unsafe impl ValueType for $t {
#[inline]
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>]) {}
}
unsafe impl<const N: usize> ValueType for [$t; N] {
#[inline]
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>]) {}
}
)*)
}
primitives! {
bool
i8 u8
i16 u16
i32 u32
i64 u64
i128 u128
isize usize
f32 f64
}
unsafe impl<T: ?Sized> ValueType for PhantomData<T> {
#[inline]
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>]) {}
}