ruknet 0.1.2

The perfect reimplementation of the RakNet protocol in Rust
Documentation
use bytes::Bytes;

use crate::reliability::fragment::Reliability;

#[derive(Debug)]
pub enum Datagram {
    Ack {
        arrival_rate: Option<f32>,
        seqs: Vec<u32>,
    },
    Nak {
        seqs: Vec<u32>,
    },
    Packet {
        is_packet_pair: bool,
        is_continuous_send: bool,
        needs_arrival_rate: bool,
        seq: u32,
        fragments: Vec<Fragment>,
    },
}

impl Datagram {
    pub const HEADER_SIZE: usize = 1;
    pub const PACKET_HEADER_SIZE: usize = 3;

    pub const IS_VALID: u8 = 0b1000_0000;
    pub const IS_ACK: u8 = 0b0100_0000;
    pub const IS_NAK: u8 = 0b0010_0000;
    pub const HAS_ARRIVAL_RATE: u8 = 0b0010_0000;
    pub const IS_PACKET_PAIR: u8 = 0b0001_0000;
    pub const IS_CONTINUOUS_SEND: u8 = 0b0000_1000;
    pub const NEEDS_ARRIVAL_RATE: u8 = 0b0000_0100;
}

#[derive(Debug, Clone, PartialEq)]
pub struct Fragment {
    pub reliability: Reliability,
    pub reliable_index: Option<u32>,
    pub sequence_index: Option<u32>,
    pub ordering_info: Option<OrderingInfo>,
    pub split_info: Option<SplitInfo>,
    pub data: Bytes,
}

#[derive(Debug, Clone, PartialEq)]
pub struct OrderingInfo {
    pub index: u32,
    pub channel: u8,
}

#[derive(Debug, Clone, PartialEq)]
pub struct SplitInfo {
    pub size: u32,
    pub id: u16,
    pub index: u32,
}

impl Fragment {
    pub const SPLIT_INFO_SIZE: usize = 10;

    pub const RELIABILITY_MASK: u8 = 0b1110_0000;
    pub const IS_SPLIT: u8 = 0b0001_0000;

    pub fn calc_header_size(&self) -> usize {
        let mut size = 1 + 2;

        if self.reliability.is_reliable() {
            size += 3;
        }
        if self.reliability.is_sequenced() {
            size += 3;
            size += 4;
        } else if self.reliability.is_ordered() {
            size += 4;
        }
        if self.split_info.is_some() {
            size += 10;
        }

        size
    }

    pub fn calc_full_size(&self) -> usize {
        self.calc_header_size() + self.data.len()
    }
}