Skip to main content

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/// Wire-level packet classification encoded in every packet header.
7#[derive(Copy, Debug, Clone, Eq, PartialEq)]
8pub enum PacketType {
9    /// Contains message, entity, and component replication data.
10    Data,
11    /// Keep-alive packet sent to prevent connection timeout.
12    Heartbeat,
13    /// Client-initiated handshake packet.
14    Handshake,
15    /// RTT probe — must be replied to with a `Pong`.
16    Ping,
17    /// RTT response to a `Ping`.
18    Pong,
19}
20
21// Most packets should be Data, so lets compress this a bit more.
22// Could do this with another enum, but code would get messy.
23impl Serde for PacketType {
24    fn ser(&self, writer: &mut dyn BitWrite) {
25        let is_data = *self == PacketType::Data;
26        is_data.ser(writer);
27
28        if is_data {
29            return;
30        }
31
32        let index = match self {
33            PacketType::Data => panic!("shouldn't happen, caught above"),
34            PacketType::Heartbeat => 0,
35            PacketType::Handshake => 1,
36            PacketType::Ping => 2,
37            PacketType::Pong => 3,
38        };
39
40        UnsignedInteger::<2>::new(index).ser(writer);
41    }
42
43    fn de(reader: &mut BitReader) -> Result<Self, SerdeErr> {
44        let is_data = bool::de(reader)?;
45        if is_data {
46            return Ok(PacketType::Data);
47        }
48
49        match UnsignedInteger::<2>::de(reader)?.get() {
50            0 => Ok(PacketType::Heartbeat),
51            1 => Ok(PacketType::Handshake),
52            2 => Ok(PacketType::Ping),
53            3 => Ok(PacketType::Pong),
54            _ => panic!("shouldn't happen, caught above"),
55        }
56    }
57
58    fn bit_length(&self) -> u32 {
59        let mut output = 0;
60
61        let is_data = *self == PacketType::Data;
62        output += is_data.bit_length();
63
64        if is_data {
65            return output;
66        }
67
68        output += <UnsignedInteger<4> as ConstBitLength>::const_bit_length();
69
70        output
71    }
72}