1use serde::{Deserialize, Serialize};
4use std::{
5 io::{Read, Write},
6 marker::PhantomData,
7};
8use xuko_core::array::{Array, ArrayCreationError};
9
10#[cfg(feature = "async")]
11use smol::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
12
13const COMPRESSION_LEVEL: i32 = 3;
14
15pub type PacketSize = u64;
20
21pub const PACKET_SIZE: usize = std::mem::size_of::<PacketSize>();
23
24static mut MAX_PACKET_SIZE: PacketSize = 2u64.pow(31) - 1;
26
27static mut PACKET_HAS_BEEN_CREATED: bool = false;
28
29pub const fn set_max_packet_size(size: PacketSize) {
33 unsafe {
34 if !PACKET_HAS_BEEN_CREATED {
35 MAX_PACKET_SIZE = size;
36 }
37 }
38}
39
40pub const fn get_max_packet_size() -> PacketSize {
42 unsafe { MAX_PACKET_SIZE }
43}
44
45#[derive(Debug, thiserror::Error)]
47pub enum PacketError {
48 #[error("packet is too large ({0} bytes)")]
50 TooLarge(usize),
51
52 #[error("{context}; expected {expected} got {real}")]
54 LengthFailure {
55 context: String,
57 expected: usize,
59 real: usize,
61 },
62
63 #[error("(de)serialization error: {0}")]
65 RonError(#[from] ron::Error),
66
67 #[error("IO error: {0}")]
69 IOError(#[from] std::io::Error),
70
71 #[error("invalid utf-8: {0}")]
73 UTF8Error(#[from] std::string::FromUtf8Error),
74
75 #[error("array creation error: {0}")]
77 ArrayCreationError(#[from] ArrayCreationError),
78}
79
80pub struct Packet<'de, T>
121where
122 T: Serialize + Deserialize<'de>,
123{
124 payload: T,
125 _marker: PhantomData<&'de T>,
126}
127
128impl<'de, T: Serialize + Deserialize<'de>> Packet<'de, T> {
129 pub const fn new(payload: T) -> Self {
131 unsafe {
132 PACKET_HAS_BEEN_CREATED = true;
133 }
134
135 Self {
136 payload,
137 _marker: PhantomData,
138 }
139 }
140
141 pub fn unwrap(self) -> T {
143 self.payload
144 }
145
146 pub fn serialize(&self) -> Result<String, ron::Error> {
148 ron::to_string(&self.payload)
149 }
150
151 pub fn deserialize(serialized: &'de str) -> Result<Packet<'de, T>, ron::Error> {
153 Ok(Self::new(ron::from_str(serialized)?))
154 }
155
156 pub fn send<W: Write>(&self, stream: &mut W) -> Result<(), PacketError> {
158 let packet = self.serialize()?;
159 let bytes = &zstd::encode_all(packet.as_bytes(), COMPRESSION_LEVEL)?;
160
161 if bytes.len() > get_max_packet_size() as usize {
162 return Err(PacketError::TooLarge(bytes.len()));
163 }
164
165 let packet_len = (bytes.len() as PacketSize).to_be_bytes();
166
167 stream.write_all(&packet_len)?;
168 stream.write_all(bytes)?;
169 stream.flush()?;
170
171 Ok(())
172 }
173
174 #[cfg(feature = "async")]
176 pub async fn send_async<W: AsyncWrite + Unpin>(
177 &self,
178 stream: &mut W,
179 ) -> Result<(), PacketError> {
180 let packet = self.serialize()?;
181 let bytes = &zstd::encode_all(packet.as_bytes(), COMPRESSION_LEVEL)?;
182
183 if bytes.len() > unsafe { MAX_PACKET_SIZE } as usize {
184 return Err(PacketError::TooLarge(bytes.len()));
185 }
186
187 let packet_len = (bytes.len() as PacketSize).to_be_bytes();
188
189 stream.write_all(&packet_len).await?;
190 stream.write_all(bytes).await?;
191 stream.flush().await?;
192
193 Ok(())
194 }
195}
196
197pub fn chomp_packet<R: Read>(stream: &mut R) -> Result<String, PacketError> {
209 let mut buf = [0u8; PACKET_SIZE];
210 let read = stream.read(&mut buf)?;
211
212 if read != PACKET_SIZE {
213 return Err(packet_size_error(PACKET_SIZE, read));
214 }
215
216 let len = PacketSize::from_be_bytes(buf) as usize;
217
218 let mut buf = Array::new(len)?;
219 let mut read = 0;
220
221 while let Ok(n) = stream.read(&mut buf) {
222 if n == 0 {
223 break;
224 }
225 read += n;
226 }
227
228 if read != len {
229 return Err(packet_bytes_read_error(len, read));
230 }
231
232 let b: &[u8] = &buf;
233 let serialized_packet = String::from_utf8(zstd::decode_all(b)?)?;
234
235 Ok(serialized_packet)
236}
237
238#[cfg(feature = "async")]
240pub async fn chomp_packet_async<R: AsyncRead + Unpin>(
241 stream: &mut R,
242) -> Result<String, PacketError> {
243 let mut buf = [0u8; PACKET_SIZE];
244 let read = stream.read(&mut buf).await?;
245
246 if read != PACKET_SIZE {
247 return Err(packet_size_error(PACKET_SIZE, read));
248 }
249
250 let len = PacketSize::from_be_bytes(buf) as usize;
251
252 let mut buf = Array::new(len)?;
253 let mut read = 0;
254
255 while let Ok(n) = stream.read(&mut buf).await {
256 if n == 0 {
257 break;
258 }
259 read += n;
260 }
261
262 if read != len {
263 return Err(packet_bytes_read_error(len, read));
264 }
265
266 let b: &[u8] = &buf;
267 let serialized_packet = String::from_utf8(zstd::decode_all(b)?)?;
268
269 Ok(serialized_packet)
270}
271
272fn packet_size_error(expected: usize, real: usize) -> PacketError {
273 PacketError::LengthFailure {
274 context: "invalid packet length".to_string(),
275 expected,
276 real,
277 }
278}
279
280fn packet_bytes_read_error(expected: usize, real: usize) -> PacketError {
281 PacketError::LengthFailure {
282 context: "didnt read expected amount of bytes from packet".to_string(),
283 expected,
284 real,
285 }
286}