nautilus_sockets/
packet.rs

1use anyhow::{anyhow, Ok};
2
3#[derive(Clone, Copy, PartialEq, Eq)]
4pub(crate) struct SocketDelivery;
5
6/// Describes how a packet will reach its target
7#[derive(Clone, Copy, PartialEq, Eq)]
8#[repr(u16)]
9pub enum PacketDelivery {
10    /// A packet which has no guarantee of reaching its target, and if it doesn't it will be
11    /// forgotten
12    Unreliable = 0,
13    /// A packet which has no guarantee of reaching its target, and will be discarded if not the
14    /// latest packet in sequence or will be forgotten if it does not reach the target
15    UnreliableSequenced = 1,
16    /// A packet which will require an acknowledgement. If the package receives no ack it will be
17    /// resent to the target
18    Reliable = 2,
19    /// A packet which will require an acknowledgement. If the package receives no ack it will be
20    /// resent to the target, however the packet may be discared if not the latest packet
21    ReliableSequenced = 3,
22
23    #[allow(private_interfaces)]
24    /// The packet delivery type for an acknowledgement packet
25    AckDelivery(SocketDelivery) = 10,
26
27    /// In place packet delivery type to request the details of the server without establishing a
28    /// connection
29    #[allow(private_interfaces)]
30    DetailRequest(SocketDelivery) = 11,
31}
32
33impl PacketDelivery {
34    /// Creates a packet delivery type for ack since it's a private interface
35    pub(crate) fn ack_delivery() -> Self {
36        Self::AckDelivery(SocketDelivery)
37    }
38
39    /// Creates a packet delivery type for detail request since it's a private interface
40    pub(crate) fn detail_request() -> Self {
41        Self::AckDelivery(SocketDelivery)
42    }
43
44    /// Is a reliable delivery type
45    pub fn is_reliable(&self) -> bool {
46        *self == Self::Reliable || *self == Self::ReliableSequenced
47    }
48
49    /// Is an unreliable delivery type
50    pub fn is_unreliable(&self) -> bool {
51        *self == Self::UnreliableSequenced || *self == Self::Unreliable
52    }
53
54    /// Is a sequenced delivery type
55    pub fn is_sequenced(&self) -> bool {
56        *self == Self::ReliableSequenced || *self == Self::UnreliableSequenced
57    }
58}
59
60impl IntoPacketDelivery<u16> for PacketDelivery {
61    fn into_packet_delivery(value: u16) -> anyhow::Result<Self> {
62        match value {
63            0 => Ok(PacketDelivery::Unreliable),
64            1 => Ok(PacketDelivery::UnreliableSequenced),
65            2 => Ok(PacketDelivery::Reliable),
66            3 => Ok(PacketDelivery::ReliableSequenced),
67            10 => Ok(PacketDelivery::ack_delivery()),
68            11 => Ok(PacketDelivery::detail_request()),
69            _ => Err(anyhow!(
70                "Cannot turn value {value} into type of PacketDelivery"
71            )),
72        }
73    }
74
75    fn packet_delivery_as(&self) -> anyhow::Result<u16> {
76        match self {
77            PacketDelivery::Unreliable => Ok(0),
78            PacketDelivery::UnreliableSequenced => Ok(1),
79            PacketDelivery::Reliable => Ok(2),
80            PacketDelivery::ReliableSequenced => Ok(3),
81            PacketDelivery::AckDelivery(SocketDelivery) => Ok(10),
82            PacketDelivery::DetailRequest(SocketDelivery) => Ok(11),
83        }
84    }
85}
86
87pub trait IntoPacketDelivery<T> {
88    fn into_packet_delivery(value: T) -> anyhow::Result<Self>
89    where
90        Self: Sized;
91
92    fn packet_delivery_as(&self) -> anyhow::Result<T>;
93}