network_protocol/core/
packet.rs

1//! # Packet
2//!
3//! This file is part of the Network Protocol project.
4//!
5//! It defines the `Packet` structure and handles all related serialization
6//! and deserialization logic.
7//!
8//! The `Packet` struct represents a fully decoded protocol packet,
9//! including the protocol version, magic header, and binary payload.
10//!
11//! This module uses the `bincode` crate for efficient binary encoding.
12//! Protocol constants like `MAGIC_BYTES` and `PROTOCOL_VERSION` are defined
13//! in the `config` module.
14//!
15//! ## Responsibilities
16//! - Decode packets from raw byte buffers
17//! - Encode `Packet` structs into raw bytes
18//! - Validate protocol headers and versions
19//!
20//! The design is optimized for performance and integration with the rest
21//! of the protocol layer.
22use crate::config::{MAGIC_BYTES, PROTOCOL_VERSION, MAX_PAYLOAD_SIZE};
23use crate::error::{ProtocolError, Result};
24
25/// Total size of the fixed-length header
26pub const HEADER_SIZE: usize = 9; // 4 magic + 1 version + 4 length
27
28/// Represents a fully decoded protocol packet
29#[derive(Debug)]
30pub struct Packet {
31    pub version: u8,
32    pub payload: Vec<u8>,
33}
34
35impl Packet {
36    /// Parse a packet from a raw buffer (header + body)
37    pub fn from_bytes(buf: &[u8]) -> Result<Self> {
38        if buf.len() < HEADER_SIZE {
39            return Err(ProtocolError::InvalidHeader);
40        }
41
42        if buf[0..4] != MAGIC_BYTES {
43            return Err(ProtocolError::InvalidHeader);
44        }
45
46        let version = buf[4];
47        if version != PROTOCOL_VERSION {
48            return Err(ProtocolError::UnsupportedVersion(version));
49        }
50
51        let length = u32::from_be_bytes([buf[5], buf[6], buf[7], buf[8]]) as usize;
52        if length > MAX_PAYLOAD_SIZE {
53            return Err(ProtocolError::OversizedPacket(length));
54        }
55
56        let payload = buf[HEADER_SIZE..].to_vec();
57        Ok(Packet { version, payload })
58    }
59
60    /// Serialize a packet to a byte vector (header + body)
61    pub fn to_bytes(&self) -> Vec<u8> {
62        let mut out = Vec::with_capacity(HEADER_SIZE + self.payload.len());
63        out.extend_from_slice(&MAGIC_BYTES);
64        out.push(PROTOCOL_VERSION);
65        out.extend_from_slice(&(self.payload.len() as u32).to_be_bytes());
66        out.extend_from_slice(&self.payload);
67        out
68    }
69}