Skip to main content

raknet_rust/protocol/
reliability.rs

1use bytes::{Buf, BufMut};
2
3use crate::error::{DecodeError, EncodeError};
4
5use super::codec::RaknetCodec;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[repr(u8)]
9pub enum Reliability {
10    Unreliable = 0,
11    UnreliableSequenced = 1,
12    Reliable = 2,
13    ReliableOrdered = 3,
14    ReliableSequenced = 4,
15    UnreliableWithAckReceipt = 5,
16    ReliableWithAckReceipt = 6,
17    ReliableOrderedWithAckReceipt = 7,
18}
19
20#[derive(Debug, Clone, Copy)]
21struct ReliabilityProps {
22    reliable: bool,
23    ordered: bool,
24    sequenced: bool,
25    with_ack_receipt: bool,
26}
27
28const RELIABILITY_PROPS: [ReliabilityProps; 8] = [
29    ReliabilityProps {
30        reliable: false,
31        ordered: false,
32        sequenced: false,
33        with_ack_receipt: false,
34    },
35    ReliabilityProps {
36        reliable: false,
37        ordered: false,
38        sequenced: true,
39        with_ack_receipt: false,
40    },
41    ReliabilityProps {
42        reliable: true,
43        ordered: false,
44        sequenced: false,
45        with_ack_receipt: false,
46    },
47    ReliabilityProps {
48        reliable: true,
49        ordered: true,
50        sequenced: false,
51        with_ack_receipt: false,
52    },
53    ReliabilityProps {
54        reliable: true,
55        ordered: false,
56        sequenced: true,
57        with_ack_receipt: false,
58    },
59    ReliabilityProps {
60        reliable: false,
61        ordered: false,
62        sequenced: false,
63        with_ack_receipt: true,
64    },
65    ReliabilityProps {
66        reliable: true,
67        ordered: false,
68        sequenced: false,
69        with_ack_receipt: true,
70    },
71    ReliabilityProps {
72        reliable: true,
73        ordered: true,
74        sequenced: false,
75        with_ack_receipt: true,
76    },
77];
78
79impl Reliability {
80    #[inline]
81    fn props(self) -> &'static ReliabilityProps {
82        &RELIABILITY_PROPS[self as usize]
83    }
84
85    #[inline]
86    pub fn is_reliable(self) -> bool {
87        self.props().reliable
88    }
89
90    #[inline]
91    pub fn is_ordered(self) -> bool {
92        self.props().ordered
93    }
94
95    #[inline]
96    pub fn is_sequenced(self) -> bool {
97        self.props().sequenced
98    }
99
100    #[inline]
101    pub fn is_with_ack_receipt(self) -> bool {
102        self.props().with_ack_receipt
103    }
104}
105
106impl TryFrom<u8> for Reliability {
107    type Error = DecodeError;
108
109    fn try_from(value: u8) -> Result<Self, Self::Error> {
110        match value {
111            0 => Ok(Self::Unreliable),
112            1 => Ok(Self::UnreliableSequenced),
113            2 => Ok(Self::Reliable),
114            3 => Ok(Self::ReliableOrdered),
115            4 => Ok(Self::ReliableSequenced),
116            5 => Ok(Self::UnreliableWithAckReceipt),
117            6 => Ok(Self::ReliableWithAckReceipt),
118            7 => Ok(Self::ReliableOrderedWithAckReceipt),
119            _ => Err(DecodeError::UnknownReliability(value)),
120        }
121    }
122}
123
124impl RaknetCodec for Reliability {
125    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
126        dst.put_u8(*self as u8);
127        Ok(())
128    }
129
130    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
131        if !src.has_remaining() {
132            return Err(DecodeError::UnexpectedEof);
133        }
134        Self::try_from(src.get_u8())
135    }
136}