naia_shared/connection/
packet_type.rs

1// An enum representing the different types of packets that can be
2// sent/received
3
4use naia_serde::{BitReader, BitWrite, ConstBitLength, Serde, SerdeErr, UnsignedInteger};
5
6#[derive(Copy, Debug, Clone, Eq, PartialEq)]
7pub enum PacketType {
8    // A packet containing Message/Entity/Component data
9    Data,
10    // A packet sent to maintain the connection by preventing a timeout
11    Heartbeat,
12    // A packet sent by the client to request a connection
13    Handshake,
14    // A Ping message, used to calculate RTT. Must be responded to with a Pong
15    // message
16    Ping,
17    // A Pong message, used to calculate RTT. Must be the response to all Ping
18    // messages
19    Pong,
20}
21
22// Most packets should be Data, so lets compress this a bit more.
23// Could do this with another enum, but code would get messy.
24impl Serde for PacketType {
25    fn ser(&self, writer: &mut dyn BitWrite) {
26        let is_data = *self == PacketType::Data;
27        is_data.ser(writer);
28
29        if is_data {
30            return;
31        }
32
33        let index = match self {
34            PacketType::Data => panic!("shouldn't happen, caught above"),
35            PacketType::Heartbeat => 0,
36            PacketType::Handshake => 1,
37            PacketType::Ping => 2,
38            PacketType::Pong => 3,
39        };
40
41        UnsignedInteger::<2>::new(index).ser(writer);
42    }
43
44    fn de(reader: &mut BitReader) -> Result<Self, SerdeErr> {
45        let is_data = bool::de(reader)?;
46        if is_data {
47            return Ok(PacketType::Data);
48        }
49
50        match UnsignedInteger::<2>::de(reader)?.get() {
51            0 => Ok(PacketType::Heartbeat),
52            1 => Ok(PacketType::Handshake),
53            2 => Ok(PacketType::Ping),
54            3 => Ok(PacketType::Pong),
55            _ => panic!("shouldn't happen, caught above"),
56        }
57    }
58
59    fn bit_length(&self) -> u32 {
60        let mut output = 0;
61
62        let is_data = *self == PacketType::Data;
63        output += is_data.bit_length();
64
65        if is_data {
66            return output;
67        }
68
69        output += <UnsignedInteger<4> as ConstBitLength>::const_bit_length();
70
71        output
72    }
73}