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) + if cfg!(debug_assertions) { MB * 3 } else { 0 } + (1024 * 10); 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}