Skip to main content

raknet_rust/protocol/
frame_header.rs

1use bytes::{Buf, BufMut};
2
3use crate::error::{DecodeError, EncodeError};
4
5use super::codec::RaknetCodec;
6use super::constants::{FRAME_FLAG_NEEDS_BAS, FRAME_FLAG_SPLIT};
7use super::reliability::Reliability;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct FrameHeader {
11    pub reliability: Reliability,
12    pub is_split: bool,
13    pub needs_bas: bool,
14}
15
16impl FrameHeader {
17    pub fn new(reliability: Reliability, is_split: bool, needs_bas: bool) -> Self {
18        Self {
19            reliability,
20            is_split,
21            needs_bas,
22        }
23    }
24
25    pub fn from_byte(raw: u8) -> Result<Self, DecodeError> {
26        let reliability = Reliability::try_from(raw >> 5)?;
27        let is_split = (raw & FRAME_FLAG_SPLIT) != 0;
28        let needs_bas = (raw & FRAME_FLAG_NEEDS_BAS) != 0;
29        Ok(Self {
30            reliability,
31            is_split,
32            needs_bas,
33        })
34    }
35
36    pub fn to_byte(self) -> u8 {
37        let mut raw = (self.reliability as u8) << 5;
38        if self.is_split {
39            raw |= FRAME_FLAG_SPLIT;
40        }
41        if self.needs_bas {
42            raw |= FRAME_FLAG_NEEDS_BAS;
43        }
44        raw
45    }
46}
47
48impl RaknetCodec for FrameHeader {
49    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
50        dst.put_u8(self.to_byte());
51        Ok(())
52    }
53
54    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
55        if !src.has_remaining() {
56            return Err(DecodeError::UnexpectedEof);
57        }
58        Self::from_byte(src.get_u8())
59    }
60}