Skip to main content

nex_packet/
packet.rs

1use bytes::{Bytes, BytesMut};
2use std::marker::PhantomData;
3
4/// Represents a generic network packet.
5pub trait Packet: Sized {
6    type Header;
7
8    /// Parse from a byte slice.
9    fn from_buf(buf: &[u8]) -> Option<Self>;
10
11    /// Parse from raw bytes. (with ownership)
12    fn from_bytes(bytes: Bytes) -> Option<Self>;
13
14    /// Serialize into raw bytes.
15    fn to_bytes(&self) -> Bytes;
16
17    /// Get the header of the packet.
18    fn header(&self) -> Bytes;
19
20    /// Get the payload of the packet.
21    fn payload(&self) -> Bytes;
22
23    /// Get the length of the header.
24    fn header_len(&self) -> usize;
25
26    /// Get the length of the payload.
27    fn payload_len(&self) -> usize;
28    /// Get the total length of the packet (header + payload).
29    fn total_len(&self) -> usize;
30
31    /// Returns true when the serialized packet is empty.
32    fn is_empty(&self) -> bool {
33        self.total_len() == 0
34    }
35    /// Convert the packet to a mutable byte buffer.
36    fn to_bytes_mut(&self) -> BytesMut {
37        let mut buf = BytesMut::with_capacity(self.total_len());
38        buf.extend_from_slice(&self.to_bytes());
39        buf
40    }
41    /// Get a mutable byte buffer for the header.
42    fn header_mut(&self) -> BytesMut {
43        let mut buf = BytesMut::with_capacity(self.header_len());
44        buf.extend_from_slice(&self.header());
45        buf
46    }
47    /// Get a mutable byte buffer for the payload.
48    fn payload_mut(&self) -> BytesMut {
49        let mut buf = BytesMut::with_capacity(self.payload_len());
50        buf.extend_from_slice(&self.payload());
51        buf
52    }
53
54    fn into_parts(self) -> (Self::Header, Bytes);
55}
56
57/// Represents a mutable network packet that can be parsed and modified in place.
58///
59/// Types implementing this trait work on top of the same backing buffer and allow
60/// layered packet parsing to be chained without additional allocations.
61pub trait MutablePacket<'a>: Sized {
62    /// The immutable packet type associated with this mutable view.
63    type Packet: Packet;
64
65    /// Construct a mutable packet from the provided buffer.
66    fn new(buffer: &'a mut [u8]) -> Option<Self>;
67
68    /// Get a shared view over the entire packet buffer.
69    fn packet(&self) -> &[u8];
70
71    /// Get a mutable view over the entire packet buffer.
72    fn packet_mut(&mut self) -> &mut [u8];
73
74    /// Get the serialized header bytes of the packet.
75    fn header(&self) -> &[u8];
76
77    /// Get a mutable view over the serialized header bytes of the packet.
78    fn header_mut(&mut self) -> &mut [u8];
79
80    /// Get the payload bytes of the packet.
81    fn payload(&self) -> &[u8];
82
83    /// Get a mutable view over the payload bytes of the packet.
84    fn payload_mut(&mut self) -> &mut [u8];
85
86    /// Returns true when the packet buffer is empty.
87    fn is_empty(&self) -> bool {
88        self.packet().is_empty()
89    }
90
91    /// Convert the mutable packet into its immutable counterpart.
92    fn freeze(&self) -> Option<Self::Packet> {
93        Self::Packet::from_buf(self.packet())
94    }
95}
96
97/// A generic mutable packet wrapper that validates using the immutable packet
98/// parser and exposes the raw buffer for in-place mutation.
99pub struct GenericMutablePacket<'a, P: Packet> {
100    buffer: &'a mut [u8],
101    _marker: PhantomData<P>,
102}
103
104impl<'a, P: Packet> MutablePacket<'a> for GenericMutablePacket<'a, P> {
105    type Packet = P;
106
107    fn new(buffer: &'a mut [u8]) -> Option<Self> {
108        P::from_buf(buffer)?;
109        Some(Self {
110            buffer,
111            _marker: PhantomData,
112        })
113    }
114
115    fn packet(&self) -> &[u8] {
116        &*self.buffer
117    }
118
119    fn packet_mut(&mut self) -> &mut [u8] {
120        &mut *self.buffer
121    }
122
123    fn header(&self) -> &[u8] {
124        let (header_len, _) = self.lengths();
125        &self.packet()[..header_len]
126    }
127
128    fn header_mut(&mut self) -> &mut [u8] {
129        let (header_len, _) = self.lengths();
130        let (header, _) = (&mut *self.buffer).split_at_mut(header_len);
131        header
132    }
133
134    fn payload(&self) -> &[u8] {
135        let (header_len, payload_len) = self.lengths();
136        &self.packet()[header_len..header_len + payload_len]
137    }
138
139    fn payload_mut(&mut self) -> &mut [u8] {
140        let (header_len, payload_len) = self.lengths();
141        let (_, payload) = (&mut *self.buffer).split_at_mut(header_len);
142        &mut payload[..payload_len]
143    }
144}
145
146impl<'a, P: Packet> GenericMutablePacket<'a, P> {
147    /// Construct a mutable packet without running additional validation.
148    pub fn new_unchecked(buffer: &'a mut [u8]) -> Self {
149        Self {
150            buffer,
151            _marker: PhantomData,
152        }
153    }
154
155    fn lengths(&self) -> (usize, usize) {
156        match P::from_buf(self.packet()) {
157            Some(packet) => {
158                let header_len = packet.header_len();
159                let payload_len = packet.payload_len();
160                (header_len, payload_len)
161            }
162            _ => (self.buffer.len(), 0),
163        }
164    }
165}