use std::mem;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[repr(C)]
#[derive(Debug, Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
pub struct GenlMsgHdr {
pub cmd: u8,
pub version: u8,
pub reserved: u16,
}
pub const GENL_HDRLEN: usize = mem::size_of::<GenlMsgHdr>();
impl GenlMsgHdr {
#[inline]
pub const fn new(cmd: u8, version: u8) -> Self {
Self {
cmd,
version,
reserved: 0,
}
}
pub fn from_bytes(data: &[u8]) -> Option<&Self> {
Self::ref_from_prefix(data).map(|(r, _)| r).ok()
}
#[inline]
pub fn as_bytes(&self) -> &[u8] {
<Self as IntoBytes>::as_bytes(self)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_genl_header_size() {
assert_eq!(GENL_HDRLEN, 4);
}
#[test]
fn test_genl_header_new() {
let hdr = GenlMsgHdr::new(1, 2);
assert_eq!(hdr.cmd, 1);
assert_eq!(hdr.version, 2);
assert_eq!(hdr.reserved, 0);
}
#[test]
fn test_genl_header_from_bytes() {
let data = [0x03, 0x01, 0x00, 0x00]; let hdr = GenlMsgHdr::from_bytes(&data).unwrap();
assert_eq!(hdr.cmd, 3);
assert_eq!(hdr.version, 1);
}
#[test]
fn test_genl_header_from_bytes_too_short() {
let data = [0x03, 0x01, 0x00]; assert!(GenlMsgHdr::from_bytes(&data).is_none());
}
#[test]
fn test_genl_header_roundtrip() {
let hdr = GenlMsgHdr::new(5, 2);
let bytes = hdr.as_bytes();
let parsed = GenlMsgHdr::from_bytes(bytes).unwrap();
assert_eq!(parsed.cmd, 5);
assert_eq!(parsed.version, 2);
}
}