ibrahim-tcp 1.0.0

High-performance lightweight TCP protocol with reliability, compression, and fault tolerance
Documentation
use lz4_flex::{compress_prepend_size, decompress_size_prepended};
use std::io::{self, Cursor, Read};

#[derive(Debug, Clone)]
pub struct Packet {
    pub id: u64,
    pub ack: bool,
    pub compressed: bool,
    pub data: String,
}

impl Packet {
    pub fn new(id: u64, data: String, compressed: bool) -> Self {
        Self {
            id,
            ack: false,
            compressed,
            data,
        }
    }

    pub fn serialize(&self) -> Vec<u8> {
        let mut payload = format!("{}|{}|{}", self.id, self.ack as u8, self.data).into_bytes();
        if self.compressed {
            payload = compress_prepend_size(&payload);
        }
        let len = (payload.len() as u32).to_be_bytes();
        [len.as_slice(), &payload].concat()
    }

    pub fn deserialize(stream: &mut Cursor<Vec<u8>>, compressed: bool) -> io::Result<Option<Self>> {
        let mut len_buf = [0u8; 4];
        if stream.read_exact(&mut len_buf).is_err() {
            return Ok(None);
        }
        let len = u32::from_be_bytes(len_buf) as usize;
        let mut payload = vec![0u8; len];
        if stream.read_exact(&mut payload).is_err() {
            return Ok(None);
        }
        let data = if compressed {
            decompress_size_prepended(&payload).map_err(|_| io::ErrorKind::InvalidData)?
        } else {
            payload
        };
        let text = String::from_utf8_lossy(&data);
        let mut parts = text.splitn(3, '|');
        let id = parts.next().unwrap_or("0").parse().unwrap_or(0);
        let ack = parts.next().unwrap_or("0") == "1";
        let data = parts.next().unwrap_or("").to_string();
        Ok(Some(Packet {
            id,
            ack,
            compressed,
            data,
        }))
    }
}