network_protocol/core/
codec.rs

1//! # Codec
2//!
3//! This file is part of the Network Protocol project.
4//!
5//! It defines the codec for encoding and decoding protocol packets using the [`Packet`] struct.
6//!
7//! The codec is designed to work with the [`tokio`] framework for asynchronous I/O.
8//! Specifically, the `PacketCodec` struct implements the [`Decoder`] and [`Encoder`] traits
9//! from [`tokio_util::codec`].
10//!
11//! ## Responsibilities
12//! - Decode packets from a byte stream
13//! - Encode packets into a byte stream
14//! - Handle fixed-length headers and variable-length payloads
15//!
16//! This module is essential for processing protocol packets in a networked environment,
17//! ensuring correct parsing and serialization.
18//!
19//! It is designed to be efficient, minimal, and easy to integrate into the protocol layer.
20//!
21
22use crate::core::packet::{Packet, HEADER_SIZE};
23use crate::error::{ProtocolError, Result};
24use bytes::{BufMut, BytesMut};
25use tokio_util::codec::{Decoder, Encoder};
26//use futures::StreamExt;
27
28pub struct PacketCodec;
29
30impl Decoder for PacketCodec {
31    type Item = Packet;
32    type Error = ProtocolError;
33
34    /// Decodes a packet from the byte stream
35    ///
36    /// Returns `None` if there aren't enough bytes to form a complete packet.
37    ///
38    /// # Errors
39    /// Returns `ProtocolError::InvalidPacket` if the packet data is malformed
40    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Packet>> {
41        if src.len() < HEADER_SIZE {
42            return Ok(None);
43        }
44
45        let len = u32::from_be_bytes([src[5], src[6], src[7], src[8]]) as usize;
46        let total_len = HEADER_SIZE + len;
47
48        if src.len() < total_len {
49            return Ok(None); // Wait for full frame
50        }
51
52        let buf = src.split_to(total_len).freeze();
53        Packet::from_bytes(&buf).map(Some)
54    }
55}
56
57impl Encoder<Packet> for PacketCodec {
58    type Error = ProtocolError;
59
60    /// Encodes a packet into the byte stream
61    ///
62    /// # Errors
63    /// This method should never fail under normal conditions, but may return protocol errors
64    /// if there are internal serialization issues
65    fn encode(&mut self, packet: Packet, dst: &mut BytesMut) -> Result<()> {
66        // Calculate total size and reserve space in the buffer
67        let total_size = HEADER_SIZE + packet.payload.len();
68        dst.reserve(total_size);
69
70        // Write header directly to buffer: magic bytes + version + length
71        dst.put_slice(&crate::config::MAGIC_BYTES);
72        dst.put_u8(crate::config::PROTOCOL_VERSION);
73        dst.put_u32(packet.payload.len() as u32);
74
75        // Write payload directly to buffer
76        dst.put_slice(&packet.payload);
77
78        Ok(())
79    }
80}