1use core::fmt::Debug;
2
3use crate::{
4 enet_packet_create, enet_packet_destroy, Box, ENetPacket, Vec, ENET_PACKET_FLAG_NO_ALLOCATE,
5 ENET_PACKET_FLAG_RELIABLE, ENET_PACKET_FLAG_SENT, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT,
6 ENET_PACKET_FLAG_UNSEQUENCED,
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum PacketKind {
14 Unreliable {
21 sequenced: bool,
23 },
24 AlwaysUnreliable {
27 sequenced: bool,
29 },
30 Reliable,
34}
35
36pub struct Packet {
42 pub(crate) packet: *mut ENetPacket,
43}
44
45unsafe impl Send for Packet {}
46unsafe impl Sync for Packet {}
47
48impl Packet {
49 #[must_use]
58 pub fn new<P: ToRawPacket>(data: P, kind: PacketKind) -> Self {
59 let kind_flags = match kind {
60 PacketKind::Unreliable { sequenced: true } => 0,
61 PacketKind::Unreliable { sequenced: false } => ENET_PACKET_FLAG_UNSEQUENCED,
62 PacketKind::AlwaysUnreliable { sequenced: true } => {
63 ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
64 }
65 PacketKind::AlwaysUnreliable { sequenced: false } => {
66 ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT | ENET_PACKET_FLAG_UNSEQUENCED
67 }
68 PacketKind::Reliable => ENET_PACKET_FLAG_RELIABLE,
69 };
70
71 let raw_packet = data.into_packet_data();
72
73 let packet = unsafe {
74 enet_packet_create(
75 raw_packet.data,
76 raw_packet.len,
77 kind_flags | ENET_PACKET_FLAG_NO_ALLOCATE,
78 )
79 };
80 unsafe {
81 (*packet).free_callback = Some(Self::drop_packet_data::<P>);
82 (*packet).user_data = raw_packet.user_data as *mut _;
83 (*packet).reference_count += 1;
84 }
85 Self { packet }
86 }
87
88 #[must_use]
91 pub fn unreliable(data: impl ToRawPacket) -> Self {
92 Self::new(data, PacketKind::Unreliable { sequenced: true })
93 }
94
95 #[must_use]
98 pub fn unreliable_unsequenced(data: impl ToRawPacket) -> Self {
99 Self::new(data, PacketKind::Unreliable { sequenced: false })
100 }
101
102 #[must_use]
105 pub fn always_unreliable(data: impl ToRawPacket) -> Self {
106 Self::new(data, PacketKind::AlwaysUnreliable { sequenced: true })
107 }
108
109 #[must_use]
112 pub fn always_unreliable_unsequenced(data: impl ToRawPacket) -> Self {
113 Self::new(data, PacketKind::AlwaysUnreliable { sequenced: false })
114 }
115
116 #[must_use]
118 pub fn reliable(data: impl ToRawPacket) -> Self {
119 Self::new(data, PacketKind::Reliable)
120 }
121
122 #[must_use]
124 pub fn kind(&self) -> PacketKind {
125 let flags = unsafe { (*self.packet).flags | !ENET_PACKET_FLAG_SENT };
126 let sequenced = flags & ENET_PACKET_FLAG_UNSEQUENCED == 0;
127 if flags & ENET_PACKET_FLAG_RELIABLE != 0 {
128 PacketKind::Reliable
129 } else if flags & ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT != 0 {
130 PacketKind::AlwaysUnreliable { sequenced }
131 } else {
132 PacketKind::Unreliable { sequenced }
133 }
134 }
135
136 #[must_use]
138 pub fn data(&self) -> &[u8] {
139 unsafe { super::from_raw_parts_or_empty((*self.packet).data, (*self.packet).data_length) }
140 }
141
142 pub(crate) fn new_from_ptr(packet: *mut ENetPacket) -> Self {
143 unsafe {
144 (*packet).reference_count += 1;
145 }
146 Self { packet }
147 }
148
149 unsafe fn drop_packet_data<P: ToRawPacket>(packet: *mut ENetPacket) {
150 P::drop_packet_data(RawPacket {
151 data: (*packet).data,
152 len: (*packet).data_length,
153 user_data: (*packet).user_data as usize,
154 });
155 }
156}
157
158impl Clone for Packet {
159 fn clone(&self) -> Self {
160 unsafe {
161 (*self.packet).reference_count += 1;
162 }
163 Self {
164 packet: self.packet,
165 }
166 }
167}
168
169impl Drop for Packet {
170 fn drop(&mut self) {
171 unsafe {
172 (*self.packet).reference_count -= 1;
173 if (*self.packet).reference_count == 0 {
174 enet_packet_destroy(self.packet);
175 }
176 }
177 }
178}
179
180impl Debug for Packet {
181 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
182 let packet = unsafe { &(*self.packet) };
183 f.debug_struct("Packet")
184 .field("data", &packet.data)
185 .field("dataLength", &packet.data_length)
186 .field("flags", &packet.flags)
187 .field("kind", &self.kind())
188 .finish()
189 }
190}
191
192pub trait ToRawPacket {
194 fn into_packet_data(self) -> RawPacket;
196
197 unsafe fn drop_packet_data(packet: RawPacket);
204}
205
206impl ToRawPacket for &[u8] {
207 fn into_packet_data(self) -> RawPacket {
208 self.to_vec().into_packet_data()
209 }
210
211 unsafe fn drop_packet_data(packet: RawPacket) {
212 Vec::<u8>::drop_packet_data(packet);
213 }
214}
215
216impl ToRawPacket for Vec<u8> {
217 fn into_packet_data(mut self) -> RawPacket {
218 let data = self.as_mut_ptr();
219 let len = self.len();
220 let user_data = self.capacity();
221 core::mem::forget(self);
222 RawPacket {
223 data,
224 len,
225 user_data,
226 }
227 }
228
229 unsafe fn drop_packet_data(packet: RawPacket) {
230 Vec::from_raw_parts(packet.data, packet.len, packet.user_data);
231 }
232}
233
234impl ToRawPacket for Box<[u8]> {
235 fn into_packet_data(self) -> RawPacket {
236 let len = self.len();
237 let data = Box::into_raw(self).cast();
238 RawPacket {
239 data,
240 len,
241 user_data: 0,
242 }
243 }
244
245 unsafe fn drop_packet_data(packet: RawPacket) {
246 let _ = Box::from_raw(core::slice::from_raw_parts_mut(packet.data, packet.len));
247 }
248}
249
250impl<T: AsRef<[u8]> + Sized> ToRawPacket for Box<T> {
251 fn into_packet_data(self) -> RawPacket {
252 let slice = (*self).as_ref();
253 let data = slice.as_ptr().cast_mut();
254 let len = slice.len();
255 let user_data = Box::into_raw(self) as usize;
256 RawPacket {
257 data,
258 len,
259 user_data,
260 }
261 }
262
263 unsafe fn drop_packet_data(packet: RawPacket) {
264 let _ = Box::<T>::from_raw(packet.user_data as *mut _);
265 }
266}
267
268pub struct RawPacket {
270 pub data: *mut u8,
272 pub len: usize,
274 pub user_data: usize,
276}