lazuli_core/
sendable.rs

1//! A module for types that can be sent over the network.
2//!
3//! This module contains the Sendable trait, which is used to convert types to bytes that can be sent over the network.
4//! The Sendable trait is implemented for all primitive types, and can be derived for custom types.
5//!
6//! Why use a Trait?
7//! - The Sendable trait allows for any type that has stuff such as heap allocations to be sent over the network.
8//! - The Sendable trait allows for optimization of the size of the type when sent over the network.
9//!     - This in particularly useful for Option<T> because it can be sent as a single byte.
10//! - The Sendable trait allows for the type to be converted to bytes in a way that is easy to implement.
11//!
12//!
13
14use core::slice;
15use std::{
16    io::{self, Read},
17    mem,
18};
19
20use log::trace;
21
22use crate::header::PacketHeader;
23use crate::Result;
24
25/// A trait for types that can be sent over the network.
26///
27/// Sendable has the Debug bound because it is internally useful, and can be helpful for debugging.
28pub trait Sendable: Sized + std::fmt::Debug {
29    /// Returns the header of the packet.
30    fn header(&self) -> PacketHeader<Self> {
31        unsafe { PacketHeader::new(self.size()) }
32    }
33
34    /// Returns the size of the type.
35    ///
36    /// **This does not return the size of the type in memory, but the size of the type when sent over the network.**
37    fn size(&self) -> u32 {
38        std::mem::size_of::<Self>() as u32
39    }
40
41    /// Converts the type to a Vec<u8> that can be sent over the network.
42    fn send(&self) -> Vec<u8>;
43
44    /// Converts an incoming stream of bytes to the type.
45    fn recv(data: &mut dyn Read) -> Result<Self>;
46}
47
48/// Converts the type to a function that can be used to convert incoming data to the type.
49/// This function hides the type of the data, allowing for the conversion function to be used in a generic context.
50///
51/// This function is used internally by `StreamConnector`.
52pub(crate) fn as_conversion_fn<T: Sendable>() -> fn(&mut dyn Read) -> Result<Box<[u8]>> {
53    |data| {
54        let conversion = Box::new(T::recv(data)?);
55        trace!("Converted to bytes: {:?}", conversion);
56        let as_slice_bytes = unsafe {
57            // We use a slice to get the bytes of the type. This is safe because we are using the size of the type to get the slice.
58            slice::from_raw_parts(
59                Box::leak(conversion) as *mut T as *mut u8,
60                mem::size_of::<T>(),
61            )
62        };
63        Ok(as_slice_bytes.into())
64    }
65}
66
67macro_rules! impl_sendable_number {
68    ($t:ty) => {
69        impl Sendable for $t {
70            fn send(&self) -> Vec<u8> {
71                // Follow the standard of big-endian
72                <$t>::to_ne_bytes(*self).to_vec()
73            }
74
75            fn recv(data: &mut dyn Read,) -> Result<Self> {
76                let mut buffer = [0; std::mem::size_of::<$t>()];
77                data.read_exact(&mut buffer)?;
78                Ok(<$t>::from_ne_bytes(buffer))
79            }
80        }
81    };
82
83    ($($t:ty),*) => {
84        $(impl_sendable_number!($t);)*
85    };
86}
87
88impl_sendable_number!(u8, u16, u32, u64, u128);
89
90impl_sendable_number!(i8, i16, i32, i64, i128);
91
92impl_sendable_number!(f32, f64);
93
94impl Sendable for bool {
95    fn send(&self) -> Vec<u8> {
96        if *self {
97            vec![1]
98        } else {
99            vec![0]
100        }
101    }
102
103    fn recv(data: &mut dyn Read) -> Result<Self> {
104        let mut buffer = [0; 1];
105        data.read_exact(&mut buffer)?;
106        Ok(buffer[0] != 0)
107    }
108}
109
110impl<T> Sendable for Vec<T>
111where
112    T: Sendable,
113{
114    fn header(&self) -> PacketHeader<Self> {
115        unsafe { PacketHeader::new(self.size()) }
116    }
117
118    fn size(&self) -> u32 {
119        let mut size = 0;
120        for item in self {
121            size += item.size();
122        }
123        size + 4
124    }
125
126    fn send(&self) -> Vec<u8> {
127        let mut data: Vec<u8> = Vec::new();
128        data.extend((self.len() as u32).send());
129        for item in self {
130            data.extend(item.send());
131        }
132        data
133    }
134
135    fn recv(data: &mut dyn Read) -> Result<Self> {
136        let mut vec = Vec::new();
137        let length = u32::recv(data)?;
138        for _ in 0..length {
139            vec.push(T::recv(data)?);
140        }
141        Ok(vec)
142    }
143}
144
145impl Sendable for String {
146    fn header(&self) -> PacketHeader<Self> {
147        unsafe { PacketHeader::new(self.size()) }
148    }
149    fn size(&self) -> u32 {
150        self.len() as u32 + 4 // Add 4 bytes for the length of the string.
151    }
152
153    fn send(&self) -> Vec<u8> {
154        let mut data = Vec::new();
155        data.extend((self.len() as u32).send());
156        data.extend(self.as_bytes());
157        data
158    }
159
160    fn recv(data: &mut dyn Read) -> Result<Self> {
161        let length = u32::recv(data)?;
162        let mut buffer = vec![0; length as usize];
163        data.read_exact(&mut buffer)?;
164        let string = String::from_utf8(buffer);
165        match string {
166            Ok(s) => {
167                trace!("Received string: {}", s);
168                Ok(s)
169            }
170            Err(_) => Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8").into()),
171        }
172    }
173}
174
175impl<T> Sendable for Option<T>
176where
177    T: Sendable,
178{
179    fn header(&self) -> PacketHeader<Self> {
180        match self {
181            Some(value) => unsafe { PacketHeader::new(value.size() + 1) },
182            None => unsafe { PacketHeader::new(1) },
183        }
184    }
185
186    fn size(&self) -> u32 {
187        match self {
188            Some(value) => value.size() + 1,
189            None => 1,
190        }
191    }
192
193    fn send(&self) -> Vec<u8> {
194        let mut data = Vec::new();
195        match self {
196            Some(value) => {
197                data.extend(true.send());
198                data.extend(value.send());
199            }
200            None => {
201                data.extend(false.send());
202            }
203        }
204        data
205    }
206
207    fn recv(data: &mut dyn Read) -> Result<Self> {
208        let is_present = bool::recv(data).unwrap();
209        if !is_present {
210            Ok(None)
211        } else {
212            Ok(Some(T::recv(data)?))
213        }
214    }
215}
216
217impl<T> Sendable for Box<T>
218where
219    T: Sendable + Copy,
220{
221    fn header(&self) -> PacketHeader<Self> {
222        unsafe { PacketHeader::new(self.size()) }
223    }
224
225    fn size(&self) -> u32 {
226        T::size(&**self)
227    }
228
229    fn send(&self) -> Vec<u8> {
230        T::send(&**self)
231    }
232
233    fn recv(data: &mut dyn Read) -> Result<Self> {
234        Ok(Box::new(T::recv(data)?))
235    }
236}
237
238macro_rules! impl_sendable_tuple {
239    ($($name:ident)+) => {
240        #[allow(non_snake_case)]
241        impl<$($name: Sendable + std::fmt::Debug,)*> Sendable for ($($name,)*) {
242            fn size(&self) -> u32{
243                let ($(ref $name,)*) = *self;
244                let mut total = 0;
245                $(total += $name.size();)*
246                total
247            }
248
249            fn send(&self) -> Vec<u8> {
250                let ($(ref $name,)*) = *self;
251                let mut buf = Vec::new();
252                $(buf.extend($name.send());)*
253                buf
254            }
255
256            fn recv(reader: &mut dyn std::io::Read) -> Result<Self >{
257                Ok(($($name::recv(reader)?,)*))
258            }
259
260        }
261    };
262}
263// Implement the Sendable trait for tuples of size 0 to 12.
264// We don't go above 12 because A. A tuple of size 12 is already pretty big, and B. Debug implements up to 12.
265impl_sendable_tuple!(A);
266impl_sendable_tuple!(A B);
267impl_sendable_tuple!(A B C);
268impl_sendable_tuple!(A B C D);
269impl_sendable_tuple!(A B C D E);
270impl_sendable_tuple!(A B C D E F);
271impl_sendable_tuple!(A B C D E F G );
272impl_sendable_tuple!(A B C D E F G H );
273impl_sendable_tuple!(A B C D E F G H I);
274impl_sendable_tuple!(A B C D E F G H I J);
275impl_sendable_tuple!(A B C D E F G H I J K);
276impl_sendable_tuple!(A B C D E F G H I J K L);
277
278impl Sendable for () {
279    fn size(&self) -> u32 {
280        0
281    }
282
283    fn send(&self) -> Vec<u8> {
284        Vec::new()
285    }
286
287    fn recv(_reader: &mut dyn std::io::Read) -> Result<Self> {
288        Ok(())
289    }
290}
291
292#[cfg(test)]
293mod tests {
294    //! Thank god for macros.
295    use super::*;
296    macro_rules! test_sendable_number {
297        ($t:ty, $name: ident) => {
298            #[test]
299            fn $name() {
300                let value: $t = 42.0 as $t;
301                let data = value.send();
302                let mut reader = std::io::Cursor::new(&data);
303                let result = <$t>::recv(&mut reader).unwrap();
304                assert_eq!(value, result);
305            }
306        };
307        ($($t:ty, $name:ident),*) => {
308            $(test_sendable_number!($t, $name);)*
309        };
310    }
311    // The vs code rust analyzer just shows like 12 run test buttons, which is mildly funny.
312    test_sendable_number!(
313        u8, test_u8, u16, test_u16, u32, test_u32, u64, test_u64, u128, test_u128, i8, test_i8,
314        i16, test_i16, i32, test_i32, i64, test_i64, i128, test_i128, f32, test_f32, f64, test_f64
315    );
316
317    macro_rules! test_sendable_vec {
318        ($t: ty, $name: ident) => {
319            #[test]
320            fn $name() {
321                let value: Vec<$t> = vec![1 as $t, 2 as $t, 3 as $t, 4 as $t, 5 as $t];
322                let data = value.send();
323                let mut reader = std::io::Cursor::new(&data);
324                let result = Vec::<$t>::recv(&mut reader).unwrap();
325                assert_eq!(value, result);
326            }
327        };
328        ($($t:ty, $name:ident),*) => {
329            $(test_sendable_vec!($t, $name);)*
330        };
331    }
332    test_sendable_vec!(
333        u8,
334        test_u8_vec,
335        u16,
336        test_u16_vec,
337        u32,
338        test_u32_vec,
339        u64,
340        test_u64_vec,
341        u128,
342        test_u128_vec,
343        i8,
344        test_i8_vec,
345        i16,
346        test_i16_vec,
347        i32,
348        test_i32_vec,
349        i64,
350        test_i64_vec,
351        i128,
352        test_i128_vec,
353        f32,
354        test_f32_vec,
355        f64,
356        test_f64_vec
357    );
358
359    #[test]
360    fn test_vec_variable_size() {
361        let mut vecs = Vec::<Vec<u8>>::new();
362        for i in 0..10 {
363            let mut vec = Vec::new();
364            for j in 0..i {
365                vec.push(j);
366            }
367            vecs.push(vec);
368        }
369        let data = vecs.send();
370        let mut reader = std::io::Cursor::new(&data);
371        let result = Vec::<Vec<u8>>::recv(&mut reader).unwrap();
372        assert_eq!(vecs, result);
373    }
374    #[test]
375    fn test_string_send() {
376        let value = "Hello, World!".to_string();
377        let data = value.send();
378        let mut reader = std::io::Cursor::new(&data);
379        let result = String::recv(&mut reader).unwrap();
380        assert_eq!(value, result);
381    }
382
383    #[test]
384    fn test_option_send_some() {
385        let value = Some(42);
386        let data = value.send();
387        assert_eq!(data[0], 1);
388        let mut reader = std::io::Cursor::new(&data);
389        let result = Option::<u32>::recv(&mut reader).unwrap();
390        assert_eq!(value, result);
391    }
392
393    #[test]
394    fn test_option_send_none() {
395        let value = None;
396        let data = value.send();
397        assert_eq!(data[0], 0);
398        let mut reader = std::io::Cursor::new(&data);
399        let result = Option::<u32>::recv(&mut reader).unwrap();
400        assert_eq!(value, result);
401    }
402
403    #[test]
404    fn test_box_send() {
405        let value = Box::new(42);
406        let data = value.send();
407        let mut reader = std::io::Cursor::new(&data);
408        let result = Box::<u32>::recv(&mut reader).unwrap();
409        assert_eq!(value, result);
410    }
411
412    #[test]
413    fn test_tuple_send() {
414        let t = (1u32, 10.0, String::from("Hello, World!"), vec![1, 2, 3, 4]);
415        let data = t.send();
416        let mut reader = std::io::Cursor::new(data);
417        let recv: (u32, f64, String, Vec<i32>) = Sendable::recv(&mut reader).unwrap();
418        assert_eq!(t, recv);
419    }
420    #[test]
421    fn test_recursive_tuple_send() {
422        let init = (1, 2);
423        let init1 = (init, init);
424        let send = (init1, init1);
425        let data = send.send();
426        let mut reader = std::io::Cursor::new(data);
427        let recv: (((i32, i32), (i32, i32)), ((i32, i32), (i32, i32))) =
428            Sendable::recv(&mut reader).unwrap();
429        assert_eq!(send, recv);
430    }
431}