net_wire/kcp/types.rs
1//! KCP scalar wire values and stateless sequence helpers.
2
3/// A KCP conversation identifier.
4#[repr(transparent)]
5#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
6pub struct KcpConversationId(u32);
7
8impl KcpConversationId {
9 /// Creates a conversation identifier from its raw wire value.
10 pub const fn new(raw: u32) -> Self {
11 Self(raw)
12 }
13
14 /// Returns the raw wire value.
15 pub const fn raw(self) -> u32 {
16 self.0
17 }
18}
19
20/// A raw KCP command byte, including values not known by this crate.
21#[repr(transparent)]
22#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
23pub struct KcpCommand(u8);
24
25impl KcpCommand {
26 /// Data segment command (`81`).
27 pub const PUSH: Self = Self(81);
28 /// Acknowledgment segment command (`82`).
29 pub const ACK: Self = Self(82);
30 /// Window-size probe command (`83`).
31 pub const WASK: Self = Self(83);
32 /// Window-size report command (`84`).
33 pub const WINS: Self = Self(84);
34
35 /// Creates a command from its raw wire value.
36 pub const fn new(raw: u8) -> Self {
37 Self(raw)
38 }
39
40 /// Returns the raw wire value.
41 pub const fn raw(self) -> u8 {
42 self.0
43 }
44
45 /// Classifies this command when it is one of KCP's upstream-defined commands.
46 pub const fn known(self) -> Option<KcpKnownCommand> {
47 KcpKnownCommand::from_raw(self.0)
48 }
49}
50
51/// A KCP command defined by the upstream wire format.
52#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
53pub enum KcpKnownCommand {
54 /// Data segment (`81`).
55 Push,
56 /// Acknowledgment segment (`82`).
57 Ack,
58 /// Window-size probe (`83`).
59 Wask,
60 /// Window-size report (`84`).
61 Wins,
62}
63
64impl KcpKnownCommand {
65 /// Classifies an upstream-defined raw command value.
66 pub const fn from_raw(raw: u8) -> Option<Self> {
67 match raw {
68 81 => Some(Self::Push),
69 82 => Some(Self::Ack),
70 83 => Some(Self::Wask),
71 84 => Some(Self::Wins),
72 _ => None,
73 }
74 }
75
76 /// Returns this command as its raw-preserving wire value.
77 pub const fn command(self) -> KcpCommand {
78 match self {
79 Self::Push => KcpCommand::PUSH,
80 Self::Ack => KcpCommand::ACK,
81 Self::Wask => KcpCommand::WASK,
82 Self::Wins => KcpCommand::WINS,
83 }
84 }
85
86 /// Returns this command's raw wire value.
87 pub const fn raw(self) -> u8 {
88 self.command().raw()
89 }
90}
91
92/// A KCP fragment number.
93#[repr(transparent)]
94#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
95pub struct KcpFragment(u8);
96
97impl KcpFragment {
98 /// Creates a fragment number from its raw wire value.
99 pub const fn new(raw: u8) -> Self {
100 Self(raw)
101 }
102
103 /// Returns the raw wire value.
104 pub const fn raw(self) -> u8 {
105 self.0
106 }
107
108 /// Returns whether this is the final fragment of a message.
109 pub const fn is_final(self) -> bool {
110 self.0 == 0
111 }
112}
113
114/// A KCP timestamp interpreted modulo 2^32.
115#[repr(transparent)]
116#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
117pub struct KcpTimestamp(u32);
118
119impl KcpTimestamp {
120 /// Creates a timestamp from its raw wire value.
121 pub const fn new(raw: u32) -> Self {
122 Self(raw)
123 }
124
125 /// Returns the raw wire value.
126 pub const fn raw(self) -> u32 {
127 self.0
128 }
129
130 /// Returns the upstream-compatible signed modular distance from `earlier` to `self`.
131 pub const fn distance_from(self, earlier: Self) -> i32 {
132 self.0.wrapping_sub(earlier.0) as i32
133 }
134
135 /// Returns whether this timestamp is before `other` in upstream-compatible modular order.
136 ///
137 /// The ordering is meaningful only when the values differ by less than half the `u32` range.
138 /// At exactly half the range, this follows upstream signed-difference behavior despite the
139 /// ambiguous modular ordering.
140 pub const fn is_before(self, other: Self) -> bool {
141 self.distance_from(other) < 0
142 }
143
144 /// Returns whether this timestamp is after `other` in upstream-compatible modular order.
145 ///
146 /// The ordering is meaningful only when the values differ by less than half the `u32` range.
147 /// At exactly half the range, this follows upstream signed-difference behavior despite the
148 /// ambiguous modular ordering.
149 pub const fn is_after(self, other: Self) -> bool {
150 self.distance_from(other) > 0
151 }
152}
153
154/// A KCP sequence number interpreted modulo 2^32.
155#[repr(transparent)]
156#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
157pub struct KcpSequenceNumber(u32);
158
159impl KcpSequenceNumber {
160 /// Creates a sequence number from its raw wire value.
161 pub const fn new(raw: u32) -> Self {
162 Self(raw)
163 }
164
165 /// Returns the raw wire value.
166 pub const fn raw(self) -> u32 {
167 self.0
168 }
169
170 /// Returns the upstream-compatible signed modular distance from `earlier` to `self`.
171 pub const fn distance_from(self, earlier: Self) -> i32 {
172 self.0.wrapping_sub(earlier.0) as i32
173 }
174
175 /// Returns whether this sequence number is before `other` in upstream-compatible modular order.
176 ///
177 /// The ordering is meaningful only when the values differ by less than half the `u32` range.
178 /// At exactly half the range, this follows upstream signed-difference behavior despite the
179 /// ambiguous modular ordering.
180 pub const fn is_before(self, other: Self) -> bool {
181 self.distance_from(other) < 0
182 }
183
184 /// Returns whether this sequence number is after `other` in upstream-compatible modular order.
185 ///
186 /// The ordering is meaningful only when the values differ by less than half the `u32` range.
187 /// At exactly half the range, this follows upstream signed-difference behavior despite the
188 /// ambiguous modular ordering.
189 pub const fn is_after(self, other: Self) -> bool {
190 self.distance_from(other) > 0
191 }
192}
193
194/// A KCP unacknowledged sequence-number marker.
195#[repr(transparent)]
196#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
197pub struct KcpUnacknowledged(u32);
198
199impl KcpUnacknowledged {
200 /// Creates an unacknowledged marker from its raw wire value.
201 pub const fn new(raw: u32) -> Self {
202 Self(raw)
203 }
204
205 /// Returns the raw wire value.
206 pub const fn raw(self) -> u32 {
207 self.0
208 }
209
210 /// Converts this marker explicitly to the corresponding sequence number.
211 pub const fn into_sequence_number(self) -> KcpSequenceNumber {
212 KcpSequenceNumber::new(self.0)
213 }
214}