1use std::{any::Any, collections::HashMap, error::Error, future::Future, io::Cursor, marker::PhantomData};
2
3use bincode::Options;
4use serde::{de::DeserializeOwned, Serialize};
5
6#[cfg(feature = "avian3d")]
11pub mod avian3d;
12
13#[cfg(feature = "base")]
14pub mod base;
15
16#[cfg(feature = "bevy")]
17pub mod bevy;
18
19#[cfg(all(feature = "bincode", not(feature = "burn_dtype")))]
20pub mod bincode;
21
22#[cfg(feature = "burn")]
23pub mod burn;
24
25#[cfg(feature = "burn_dtype")]
26pub mod burn_dtype;
27
28#[cfg(feature = "glam")]
29pub mod glam;
30
31#[cfg(feature = "rand")]
32pub mod rand;
33
34#[cfg(feature = "rustls")]
35pub mod rustls;
36
37#[cfg(feature = "tokio")]
38pub mod tokio;
39
40pub trait ByteConverter {
41 fn append_to_bytes(&self, bytes: &mut Vec<u8>) -> Result<(), Box<dyn Error + Send + Sync + 'static>>;
42 fn extract_from_bytes<'a, TBytes: AsRef<[u8]>>(bytes: &'a TBytes, index: &mut usize) -> Result<Self, Box<dyn Error + Send + Sync + 'static>> where Self: Sized;
43 #[inline(always)]
44 fn to_vec_bytes(&self) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>> {
45 let mut bytes = Vec::new();
46 self.append_to_bytes(&mut bytes)?;
47 Ok(bytes)
48 }
49 #[inline(always)]
50 fn to_vec_bytes_with_capacity(&self, capacity: usize) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>> {
51 let mut bytes = Vec::with_capacity(capacity);
52 self.append_to_bytes(&mut bytes)?;
53 Ok(bytes)
54 }
55 #[inline(always)]
56 fn clone_via_bytes(&self) -> Result<Self, Box<dyn Error + Send + Sync + 'static>> where Self: Sized {
57 let bytes = self.to_vec_bytes()?;
58 Self::deserialize_from_bytes(&bytes)
59 }
60 #[inline(always)]
62 fn deserialize_from_bytes<'a, TBytes: AsRef<[u8]>>(bytes: &'a TBytes) -> Result<Self, Box<dyn Error + Send + Sync + 'static>> where Self: Sized {
63 let bytes_ref = bytes.as_ref();
64 let mut index = 0;
65 let instance = Self::extract_from_bytes(bytes, &mut index)?;
66 if index != bytes_ref.len() {
67 return Err("The provided bytes contained more than one instance of a type. Deserializing did not exhaust the total length of the provided bytes.".into());
68 }
69 Ok(instance)
70 }
71 #[inline(always)]
73 fn cast_via_bytes<TByteConverter>(&self) -> Result<TByteConverter, Box<dyn Error + Send + Sync + 'static>> where TByteConverter: ByteConverter {
74 let bytes = self.to_vec_bytes()?;
75 TByteConverter::deserialize_from_bytes(&bytes)
76 }
77}
78pub trait ByteStreamReader {
79 fn read_to_byte_converter<T: ByteConverter>(&mut self) -> Result<T, Box<dyn Error + Send + Sync + 'static>>;
80}
81
82pub trait ByteStreamReaderAsync {
83 fn read_to_byte_converter<T: ByteConverter>(&mut self) -> impl Future<Output = Result<T, Box<dyn Error + Send + Sync + 'static>>>;
84}
85
86pub trait ByteStreamWriter {
87 fn write_from_byte_converter(&mut self, byte_converter: &impl ByteConverter) -> Result<(), Box<dyn Error + Send + Sync + 'static>>;
88}
89
90pub trait ByteStreamWriterAsync {
91 fn write_from_byte_converter(&mut self, byte_converter: &impl ByteConverter) -> impl Future<Output = Result<(), Box<dyn Error + Send + Sync + 'static>>>;
92}
93
94#[derive(thiserror::Error, Debug)]
95enum ByteConverterError {
96 #[error("Index {index} out of range of bytes array with length {length}.")]
97 IndexOutOfRange {
98 index: usize,
99 length: usize,
100 },
101 #[error("Failed to extract 64-bit usize on this machine.")]
102 FailedToExtractSixtyFourBitUsize,
103 #[error("Unexpected number of bytes {bytes_length} for usize that expects either 4 or 8.")]
104 UnexpectedSizeOfUsize {
105 bytes_length: usize,
106 },
107 #[error("Unexpected byte value {byte_value} when trying to parse to boolean value of 0 or 1.")]
108 UnexpectedByteValueForBoolean {
109 byte_value: u8,
110 },
111 #[error("Failed to convert from {from_type} to {to_type}.")]
112 FailedToConvertToType {
113 from_type: String,
114 to_type: String,
115 },
116 #[error("Unexpected byte value {byte_value} when trying to parse to Option value of Some or None.")]
117 UnexpectedByteValueForOption {
118 byte_value: u8,
119 },
120 #[error("Failed to lock mutex.")]
121 FailedToLockMutex,
122}
123
124#[inline(always)]
125fn get_single_byte<TBytes: AsRef<[u8]>>(bytes: TBytes, index: &mut usize) -> Result<u8, Box<dyn Error + Send + Sync + 'static>> {
126 let bytes_ref = bytes.as_ref();
127 let bytes_length = bytes_ref.len();
128 let index_deref = *index;
129 let next_index = index_deref + 1;
130 if bytes_length < next_index {
131 return Err(ByteConverterError::IndexOutOfRange {
132 index: next_index,
133 length: bytes_length,
134 }.into());
135 }
136 let byte = bytes_ref[index_deref];
137 *index = next_index;
138 Ok(byte)
139}
140
141#[inline(always)]
142fn get_multiple_bytes<'a, TBytes: AsRef<[u8]>>(bytes: &'a TBytes, index: &mut usize, size: usize) -> Result<&'a [u8], Box<dyn Error + Send + Sync + 'static>> {
143 let bytes_ref = bytes.as_ref();
144 let bytes_length = bytes_ref.len();
145 let index_deref = *index;
146 let next_index = index_deref + size;
147 if bytes_length < next_index {
148 return Err(ByteConverterError::IndexOutOfRange {
149 index: next_index,
150 length: bytes_length,
151 }.into());
152 }
153 let multiple_bytes = &bytes_ref[index_deref..next_index];
154 *index = next_index;
155 Ok(multiple_bytes)
156}
157
158struct TypedSerializationByteConverterRegistration {
159 extract_bytes_from_context_function: fn(&mut dyn Context) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>>,
160}
161
162impl TypedSerializationByteConverterRegistration {
163 #[inline(always)]
164 fn extract_bytes_from_context(&self, context: &mut dyn Context) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>> {
165 (self.extract_bytes_from_context_function)(context)
166 }
167}
168
169struct TypedDeserializationByteConverterRegistration<TOutput, TByteConverter> {
170 apply_function: fn(&mut dyn Context) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>>,
171 byte_converter_phantom_data: PhantomData<TByteConverter>,
172}
173
174impl<TOutput, TByteConverter> TypedDeserializationByteConverterRegistration<TOutput, TByteConverter> {
175 #[inline(always)]
176 fn extract_byte_converter_from_context_and_apply(&self, context: &mut dyn Context) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>> {
177 (self.apply_function)(context)
178 }
179}
180
181struct UntypedSerializationByteConverterRegistration {
182 type_name: &'static str,
183 extract_bytes_from_context_function: unsafe fn(),
184}
185
186impl UntypedSerializationByteConverterRegistration {
187 pub fn new<TByteConverter, TContext>(
188 extract_bytes_from_context_function: fn(&mut TContext) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>>,
189 ) -> Self
190 where
191 TByteConverter: ByteConverter + Any,
192 TContext: Context,
193 {
194 Self {
195 type_name: std::any::type_name::<TByteConverter>(),
196 extract_bytes_from_context_function: unsafe { std::mem::transmute::<fn(&mut TContext) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>>, unsafe fn()>(extract_bytes_from_context_function) },
197 }
198 }
199 #[inline(always)]
200 fn cast<TByteConverter, TContext>(&self) -> TypedSerializationByteConverterRegistration
201 where
202 TContext: Context,
203 {
204 TypedSerializationByteConverterRegistration {
205 extract_bytes_from_context_function: unsafe { std::mem::transmute::<unsafe fn(), fn(&mut dyn Context) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>>>(self.extract_bytes_from_context_function) },
206 }
207 }
208}
209
210struct UntypedDeserializationByteConverterRegistration<TOutput> {
211 type_name: &'static str,
212 apply_function: unsafe fn(),
213 phantom_output: std::marker::PhantomData<TOutput>,
214}
215
216impl<TOutput> UntypedDeserializationByteConverterRegistration<TOutput> {
217 pub fn new<TByteConverter, TContext>(
218 apply_function: fn(&mut TContext) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>>,
219 ) -> Self
220 where
221 TByteConverter: ByteConverter + Any,
222 TContext: Context,
223 {
224 Self {
225 type_name: std::any::type_name::<TByteConverter>(),
226 apply_function: unsafe { std::mem::transmute::<fn(&mut TContext) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>>, unsafe fn()>(apply_function) },
227 phantom_output: PhantomData::default(),
228 }
229 }
230 #[inline(always)]
231 fn cast<TByteConverter>(&self) -> TypedDeserializationByteConverterRegistration<TOutput, TByteConverter> {
232 TypedDeserializationByteConverterRegistration::<TOutput, TByteConverter> {
233 apply_function: unsafe { std::mem::transmute::<unsafe fn(), fn(&mut dyn Context) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>>>(self.apply_function) },
234 byte_converter_phantom_data: PhantomData::default(),
235 }
236 }
237}
238
239#[inline(always)]
240fn extract_bytes_from_context<TContext, TByteConverter>(
241 untyped_byte_converter_registration: &UntypedSerializationByteConverterRegistration,
242 context: &mut dyn Context,
243) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>>
244where
245 TByteConverter: ByteConverter,
246 TContext: Context,
247{
248 untyped_byte_converter_registration.cast::<TByteConverter, TContext>().extract_bytes_from_context(context)
249}
250
251#[inline(always)]
252fn extract_byte_converter_from_context_and_apply<TOutput, TByteConverter>(
253 untyped_byte_converter_registration: &UntypedDeserializationByteConverterRegistration<TOutput>,
254 context: &mut dyn Context,
255) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>> {
256 untyped_byte_converter_registration.cast::<TByteConverter>().extract_byte_converter_from_context_and_apply(context)
257}
258
259pub struct SerializationByteConverterFactory {
260 untyped_byte_converter_registration_per_type_name: HashMap<&'static str, (
261 UntypedSerializationByteConverterRegistration,
262 fn(&UntypedSerializationByteConverterRegistration, &mut dyn Context) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>>,
263 )>,
264}
265
266impl Default for SerializationByteConverterFactory {
267 fn default() -> Self {
268 Self {
269 untyped_byte_converter_registration_per_type_name: HashMap::new(),
270 }
271 }
272}
273
274impl SerializationByteConverterFactory
275{
276 pub fn register<TByteConverter, TContext>(
277 &mut self,
278 extract_bytes_from_context_function: fn(&mut TContext) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>>,
279 ) -> &mut Self
280 where
281 TByteConverter: ByteConverter + 'static,
282 TContext: Context,
283 {
284 let untyped_byte_converter_registration = UntypedSerializationByteConverterRegistration::new::<TByteConverter, TContext>(extract_bytes_from_context_function);
285 self.untyped_byte_converter_registration_per_type_name.insert(
286 untyped_byte_converter_registration.type_name,
287 (
288 untyped_byte_converter_registration,
289 extract_bytes_from_context::<TContext, TByteConverter>,
290 ),
291 );
292 self
293 }
294 pub fn get_registered_type_names(&self) -> Vec<&'static str> {
295 self.untyped_byte_converter_registration_per_type_name.keys()
296 .into_iter()
297 .cloned()
298 .collect::<Vec<_>>()
299 }
300 #[inline(always)]
301 pub fn serialize(&self, context: &mut dyn Context, type_name: &str) -> Result<Vec<u8>, Box<dyn Error + Sync + Send + 'static>>
302 {
303 let Some((untyped_byte_converter_registration, apply)) = self.untyped_byte_converter_registration_per_type_name.get(&type_name) else {
304 return Err("type_name not registered to any ByteConverter.".into());
305 };
306 let output = apply(untyped_byte_converter_registration, context)?;
307 Ok(output)
308 }
309}
310
311pub trait Context {}
312
313pub struct DeserializationByteConverterFactory<TOutput> {
314 untyped_byte_converter_registration_per_type_name: HashMap<&'static str, (
315 UntypedDeserializationByteConverterRegistration<TOutput>,
316 fn(&UntypedDeserializationByteConverterRegistration<TOutput>, &mut dyn Context) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>>,
317 )>,
318}
319
320impl<TOutput> Default for DeserializationByteConverterFactory<TOutput> {
321 fn default() -> Self {
322 Self {
323 untyped_byte_converter_registration_per_type_name: HashMap::new(),
324 }
325 }
326}
327
328impl<TOutput> DeserializationByteConverterFactory<TOutput>
329{
330 pub fn register<TByteConverter, TContext>(
331 &mut self,
332 apply_function: fn(&mut TContext) -> Result<TOutput, Box<dyn Error + Send + Sync + 'static>>,
333 ) -> &mut Self
334 where
335 TByteConverter: ByteConverter + 'static,
336 TContext: Context,
337 {
338 let untyped_byte_converter_registration = UntypedDeserializationByteConverterRegistration::new::<TByteConverter, TContext>(apply_function);
339 self.untyped_byte_converter_registration_per_type_name.insert(
340 untyped_byte_converter_registration.type_name,
341 (
342 untyped_byte_converter_registration,
343 extract_byte_converter_from_context_and_apply::<TOutput, TByteConverter>,
344 ),
345 );
346 self
347 }
348 pub fn get_registered_type_names(&self) -> Vec<&'static str> {
349 self.untyped_byte_converter_registration_per_type_name.keys()
350 .into_iter()
351 .cloned()
352 .collect::<Vec<_>>()
353 }
354 #[inline(always)]
355 pub fn deserialize(&self, context: &mut dyn Context, type_name: &str) -> Result<TOutput, Box<dyn Error + Sync + Send + 'static>>
356 {
357 let Some((untyped_byte_converter_registration, apply)) = self.untyped_byte_converter_registration_per_type_name.get(&type_name) else {
358 return Err("type_name not registered to any ByteConverter.".into());
359 };
360 let output = apply(untyped_byte_converter_registration, context)?;
361 Ok(output)
362 }
363}
364
365pub struct BincodeByteConverter<TByteConverter>(TByteConverter)
367where
368 TByteConverter: ByteConverter + Serialize + DeserializeOwned;
369
370impl<TByteConverter> ByteConverter for BincodeByteConverter<TByteConverter>
371where
372 TByteConverter: ByteConverter + Serialize + DeserializeOwned,
373{
374 #[inline(always)]
375 fn append_to_bytes(&self, bytes: &mut Vec<u8>) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
376 let serialized = bincode::serialize(&self.0)?;
377 bytes.extend_from_slice(&serialized);
378 Ok(())
379 }
380 #[inline(always)]
381 fn extract_from_bytes<'a, TBytes: AsRef<[u8]>>(bytes: &'a TBytes, index: &mut usize) -> Result<Self, Box<dyn Error + Send + Sync + 'static>> where Self: Sized {
382 let bytes_ref = bytes.as_ref();
383 let mut cursor = Cursor::new(&bytes_ref[*index..]);
384 let output: TByteConverter = bincode::options().deserialize_from(&mut cursor)?;
385 *index += cursor.position() as usize;
386 Ok(Self(output))
387 }
388}