use crate::core::packet::{Packet, HEADER_SIZE};
use crate::error::{ProtocolError, Result};
use bytes::{BufMut, BytesMut};
use tokio_util::codec::{Decoder, Encoder};
pub struct PacketCodec;
impl Decoder for PacketCodec {
type Item = Packet;
type Error = ProtocolError;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Packet>> {
if src.len() < HEADER_SIZE {
return Ok(None);
}
let len = u32::from_be_bytes([src[5], src[6], src[7], src[8]]) as usize;
let total_len = HEADER_SIZE + len;
if src.len() < total_len {
return Ok(None); }
let buf = src.split_to(total_len).freeze();
Packet::from_bytes(&buf).map(Some)
}
}
impl Encoder<Packet> for PacketCodec {
type Error = ProtocolError;
fn encode(&mut self, packet: Packet, dst: &mut BytesMut) -> Result<()> {
let total_size = HEADER_SIZE + packet.payload.len();
dst.reserve(total_size);
dst.put_slice(&crate::config::MAGIC_BYTES);
dst.put_u8(crate::config::PROTOCOL_VERSION);
dst.put_u32(packet.payload.len() as u32);
dst.put_slice(&packet.payload);
Ok(())
}
}