use crate::config::{MAGIC_BYTES, MAX_PAYLOAD_SIZE, PROTOCOL_VERSION};
use crate::error::{ProtocolError, Result};
pub const HEADER_SIZE: usize = 9;
#[derive(Debug, Clone)]
pub struct Packet {
pub version: u8,
pub payload: Vec<u8>,
}
impl Packet {
pub fn from_bytes(buf: &[u8]) -> Result<Self> {
if buf.len() < HEADER_SIZE {
return Err(ProtocolError::InvalidHeader);
}
if buf[0..4] != MAGIC_BYTES {
return Err(ProtocolError::InvalidHeader);
}
let version = buf[4];
if version != PROTOCOL_VERSION {
return Err(ProtocolError::UnsupportedVersion(version));
}
let length = u32::from_be_bytes([buf[5], buf[6], buf[7], buf[8]]) as usize;
if length > MAX_PAYLOAD_SIZE {
return Err(ProtocolError::OversizedPacket(length));
}
let payload = buf[HEADER_SIZE..].to_vec();
Ok(Packet { version, payload })
}
pub fn to_bytes(&self) -> Vec<u8> {
let mut out = Vec::with_capacity(HEADER_SIZE + self.payload.len());
out.extend_from_slice(&MAGIC_BYTES);
out.push(self.version);
out.extend_from_slice(&(self.payload.len() as u32).to_be_bytes());
out.extend_from_slice(&self.payload);
out
}
}