#[pod_union]Expand description
An attribute macro that enables safe usage of unions as POD types.
Rust’s built-in unions cannot directly derive zerocopy::IntoBytes because unions require
field-by-field initialization and access. The #[pod_union] macro solves this by
transforming a union into a safe wrapper struct.
§Implementation details
When you write:
use ostd_pod_macros::pod_union;
#[repr(C)]
#[pod_union]
#[derive(Clone, Copy)]
pub union Data {
value: u64,
bytes: [u8; 4],
}The #[pod_union] macro internally generates something equivalent to:
use ostd_pod::array_helper::{ArrayFactory, ArrayManufacture, U64Array};
use ostd_pod::{FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout, Pod};
// Internal private union
#[repr(C)]
#[derive(FromBytes, KnownLayout, Immutable)]
union __Data__ {
value: u64,
bytes: [u8; 4],
}
// Public wrapper struct that provides safe access
#[repr(transparent)]
#[derive(FromBytes, KnownLayout, Immutable, IntoBytes)]
pub struct Data(<ArrayFactory<
{ align_of::<__Data__>() },
{ size_of::<__Data__>() / (align_of::<__Data__>()) },
> as ArrayManufacture>::Array);
impl Data {
// Field accessor methods
pub fn value(&self) -> &u64 {
u64::ref_from_bytes(&self.0.as_bytes()[..8]).unwrap()
}
pub fn value_mut(&mut self) -> &mut u64 {
u64::mut_from_bytes(&mut self.0.as_mut_bytes()[..8]).unwrap()
}
pub fn bytes(&self) -> &[u8; 4] {
<[u8; 4]>::ref_from_bytes(&self.0.as_bytes()[..4]).unwrap()
}
pub fn bytes_mut(&mut self) -> &mut [u8; 4] {
<[u8; 4]>::mut_from_bytes(&mut self.0.as_mut_bytes()[..4]).unwrap()
}
// Initializer methods
pub fn new_value(value: u64) -> Self {
let mut slf = Self::new_zeroed();
*slf.value_mut() = value;
slf
}
pub fn new_bytes(bytes: [u8; 4]) -> Self {
let mut slf = Self::new_zeroed();
*slf.bytes_mut() = bytes;
slf
}
}