bytes_kman/core/
mod.rs

1use crate::{TBuffer, TBytes};
2
3pub mod num;
4pub mod option;
5pub mod primitive;
6pub mod result;
7pub mod tuple;
8
9impl<T: TBytes, const LEN: usize> TBytes for [T; LEN] {
10    fn size(&self) -> usize {
11        let mut size = 0;
12        for p in self.iter() {
13            size += p.size();
14        }
15        size
16    }
17
18    fn to_bytes(&self) -> Vec<u8> {
19        let mut buffer = Vec::with_capacity(self.size());
20
21        for p in self.iter() {
22            buffer.append(&mut p.to_bytes())
23        }
24
25        buffer
26    }
27
28    fn from_bytes(buffer: &mut TBuffer) -> Option<Self>
29    where
30        Self: Sized,
31    {
32        let mut array = core::mem::MaybeUninit::<[T; LEN]>::uninit();
33
34        for index in 0..LEN {
35            if let Some(value) = T::from_bytes(buffer) {
36                unsafe { std::ptr::write(&mut array.assume_init_mut()[index], value) };
37            } else {
38                for i in 0..index {
39                    let index = (index - 1) - i;
40                    buffer.reverse();
41                    unsafe {
42                        let item = &mut array.assume_init_mut()[index];
43                        buffer.extend(item.to_bytes().iter().rev());
44                        core::ptr::drop_in_place(item);
45                    }
46                    buffer.reverse();
47                }
48                return None;
49            }
50        }
51
52        Some(unsafe { array.assume_init() })
53    }
54}
55
56#[cfg(test)]
57mod test {
58    use crate::TBytes;
59
60    #[test]
61    fn array_i32() {
62        let a = [32, 543, 61, 21215, -4236, 32];
63
64        let mut bytes = a.to_bytes();
65
66        let other = <[i32; 6]>::from_bytes(&mut bytes).unwrap();
67
68        assert_eq!(a, other);
69    }
70
71    #[test]
72    fn array_string() {
73        let a = [
74            "Hello World!".to_string(),
75            "This is working???".into(),
76            "Is working as is supposed!".into(),
77        ];
78
79        let mut bytes = a.to_bytes();
80
81        let other = <[String; 3]>::from_bytes(&mut bytes).unwrap();
82
83        assert_eq!(a, other);
84    }
85
86    #[test]
87    fn array_incomplete() {
88        let mut buffer = Vec::new();
89        let strings = ["Where", "Are", "You", "From"].map(|w| w.to_string());
90        for string in &strings[0..3] {
91            buffer.append(&mut string.to_bytes());
92        }
93        let clone_buffer = buffer.clone();
94
95        let other_buffer = <[String; 4]>::from_bytes(&mut buffer);
96        if let Some(other_buffer) = other_buffer {
97            panic!("This should be possible! Other buffer: {other_buffer:?}");
98        }
99
100        assert_eq!(buffer, clone_buffer);
101        buffer.append(&mut strings[3].to_bytes());
102
103        let value = <[String; 4]>::from_bytes(&mut buffer).unwrap();
104        assert_eq!(value, strings)
105    }
106
107    #[test]
108    fn array_drop_and_incomplete_drop() {
109        use crate::prelude::*;
110
111        thread_local! { static LAST_DROPED: core::cell::Cell<u32> = const {core::cell::Cell::<u32>::new(0)}};
112
113        #[derive(Bytes)]
114        struct ToDrop {
115            id: u32,
116        }
117
118        impl Drop for ToDrop {
119            fn drop(&mut self) {
120                LAST_DROPED.set(self.id);
121            }
122        }
123
124        let mut buffer = Vec::new();
125        {
126            buffer.append(&mut ToDrop { id: 1 }.to_bytes());
127        }
128        assert_eq!(LAST_DROPED.get(), 1);
129        {
130            buffer.append(&mut ToDrop { id: 2 }.to_bytes());
131        }
132        assert_eq!(LAST_DROPED.get(), 2);
133        let buffer_clone = buffer.clone();
134
135        LAST_DROPED.set(0);
136
137        let other_buffer = <[ToDrop; 2]>::from_bytes(&mut buffer).unwrap();
138        assert_eq!(LAST_DROPED.get(), 0);
139        assert_eq!(other_buffer.to_bytes(), buffer_clone);
140
141        buffer = buffer_clone.clone();
142        assert!(<[ToDrop; 3]>::from_bytes(&mut buffer).is_none());
143        assert_eq!(LAST_DROPED.get(), 1);
144        assert_eq!(other_buffer.to_bytes(), buffer_clone);
145    }
146
147    #[test]
148    fn array_1mb() {
149        const MB: usize = 1024 * 1024;
150        const STACK_SIZE: usize = (MB * 3) // needed for slices
151                                + if cfg!(debug_assertions) { MB * 3 } else { 0 } // debug
152                                + (1024 * 10); // 10KB code stack
153
154        std::thread::Builder::new()
155            .stack_size(STACK_SIZE)
156            .name(format!("{}MB stack", STACK_SIZE / MB))
157            .spawn(|| {
158                let mut buffer = {
159                    let a = [0u8; MB];
160                    a.to_bytes()
161                };
162                let buffer_clone = buffer.clone();
163                let res = <[u8; MB]>::from_bytes(&mut buffer).unwrap();
164                assert_eq!(res.to_bytes(), buffer_clone);
165            })
166            .unwrap()
167            .join()
168            .unwrap();
169    }
170}