macro_rules! static_assert_eq_usize {
($lhs:expr, $rhs:expr) => {
const _: [(); $lhs] = [(); $rhs];
}
}
macro_rules! assert_layout {
{
$(
$t:ident (size = $size:expr, align = $align:expr) {
$($member:ident @ $offset:expr,)*
}
)*
} => {
$(
static_assert_eq_usize!($size, std::mem::size_of::());
static_assert_eq_usize!($align, std::mem::align_of::());
$(static_assert_eq_usize!($offset, std::mem::offset_of!($t, $member));)*
)*
}
}
#[repr(C)]
struct LogHeader {
magic: u64,
version: u64,
length: u64,
}
#[repr(C, packed(4))]
struct LogEntry {
timestamp: u32,
data: u64,
}
assert_layout! {
LogHeader (size = 24, align = 8) {
magic @ 0,
version @ 8,
length @ 16,
}
LogEntry (size = 12, align = 4) {
timestamp @ 0,
data @ 4,
}
}
($lhs:expr, $rhs:expr) => {
const _: [(); $lhs] = [(); $rhs];
}
}
macro_rules! assert_layout {
{
$(
$t:ident (size = $size:expr, align = $align:expr) {
$($member:ident @ $offset:expr,)*
}
)*
} => {
$(
static_assert_eq_usize!($size, std::mem::size_of::());
static_assert_eq_usize!($align, std::mem::align_of::());
$(static_assert_eq_usize!($offset, std::mem::offset_of!($t, $member));)*
)*
}
}
#[repr(C)]
struct LogHeader {
magic: u64,
version: u64,
length: u64,
}
#[repr(C, packed(4))]
struct LogEntry {
timestamp: u32,
data: u64,
}
assert_layout! {
LogHeader (size = 24, align = 8) {
magic @ 0,
version @ 8,
length @ 16,
}
LogEntry (size = 12, align = 4) {
timestamp @ 0,
data @ 4,
}
}