use crate::error::{Error, Result, eyre};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, IntoBytes)]
pub struct PacketHeader {
pub length: [u8; 3],
pub sequence_id: u8,
}
impl PacketHeader {
pub fn encode(length: usize, sequence_id: u8) -> Self {
let len = u32::to_le_bytes(length as u32);
Self {
length: [len[0], len[1], len[2]],
sequence_id,
}
}
pub fn encode_in_place(&mut self, length: usize, sequence_id: u8) {
let len = u32::to_le_bytes(length as u32);
self.length = [len[0], len[1], len[2]];
self.sequence_id = sequence_id;
}
pub fn length(&self) -> usize {
u32::from_le_bytes([self.length[0], self.length[1], self.length[2], 0]) as usize
}
pub fn from_bytes(data: &[u8]) -> Result<&Self> {
if data.len() < 4 {
return Err(Error::LibraryBug(eyre!(
"packet header too short: {} < 4",
data.len()
)));
}
Ok(Self::ref_from_bytes(&data[..4])?)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn packet_header_has_alignment_of_1() {
assert_eq!(std::mem::align_of::<PacketHeader>(), 1);
}
}