const_serialize/const_vec.rs
1#![allow(dead_code)]
2use std::{fmt::Debug, hash::Hash, mem::MaybeUninit};
3
4use crate::ConstReadBuffer;
5
6const DEFAULT_MAX_SIZE: usize = 2usize.pow(10);
7
8/// [`ConstVec`] is a version of [`Vec`] that is usable in const contexts. It has
9/// a fixed maximum size, but it can can grow and shrink within that size limit
10/// as needed.
11///
12/// # Example
13/// ```rust
14/// # use const_serialize::ConstVec;
15/// const EMPTY: ConstVec<u8> = ConstVec::new();
16/// // Methods that mutate the vector will return a new vector
17/// const ONE: ConstVec<u8> = EMPTY.push(1);
18/// const TWO: ConstVec<u8> = ONE.push(2);
19/// const THREE: ConstVec<u8> = TWO.push(3);
20/// const FOUR: ConstVec<u8> = THREE.push(4);
21/// // If a value is also returned, that will be placed in a tuple in the return value
22/// // along with the new vector
23/// const POPPED: (ConstVec<u8>, Option<u8>) = FOUR.pop();
24/// assert_eq!(POPPED.0, THREE);
25/// assert_eq!(POPPED.1.unwrap(), 4);
26/// ```
27pub struct ConstVec<T, const MAX_SIZE: usize = DEFAULT_MAX_SIZE> {
28 memory: [MaybeUninit<T>; MAX_SIZE],
29 len: u32,
30}
31
32impl<T: Clone, const MAX_SIZE: usize> Clone for ConstVec<T, MAX_SIZE> {
33 fn clone(&self) -> Self {
34 let mut cloned = Self::new_with_max_size();
35 for i in 0..self.len as usize {
36 cloned = cloned.push(self.get(i).unwrap().clone());
37 }
38 cloned
39 }
40}
41
42impl<T: Copy, const MAX_SIZE: usize> Copy for ConstVec<T, MAX_SIZE> {}
43
44impl<T: PartialEq, const MAX_SIZE: usize> PartialEq for ConstVec<T, MAX_SIZE> {
45 fn eq(&self, other: &Self) -> bool {
46 self.as_ref() == other.as_ref()
47 }
48}
49
50impl<T: Hash, const MAX_SIZE: usize> Hash for ConstVec<T, MAX_SIZE> {
51 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
52 self.as_ref().hash(state)
53 }
54}
55
56impl<T, const MAX_SIZE: usize> Default for ConstVec<T, MAX_SIZE> {
57 fn default() -> Self {
58 Self::new_with_max_size()
59 }
60}
61
62impl<T: Debug, const MAX_SIZE: usize> Debug for ConstVec<T, MAX_SIZE> {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 f.debug_struct("ConstVec")
65 .field("len", &self.len)
66 .field("memory", &self.as_ref())
67 .finish()
68 }
69}
70
71impl<T> ConstVec<T> {
72 /// Create a new empty [`ConstVec`]
73 pub const fn new() -> Self {
74 Self::new_with_max_size()
75 }
76}
77
78impl<T, const MAX_SIZE: usize> ConstVec<T, MAX_SIZE> {
79 /// Create a new empty [`ConstVec`] with a custom maximum size
80 ///
81 /// # Example
82 /// ```rust
83 /// # use const_serialize::ConstVec;
84 /// const EMPTY: ConstVec<u8, 10> = ConstVec::new_with_max_size();
85 /// ```
86 pub const fn new_with_max_size() -> Self {
87 Self {
88 memory: [const { MaybeUninit::uninit() }; MAX_SIZE],
89 len: 0,
90 }
91 }
92
93 /// Push a value onto the end of the [`ConstVec`]
94 ///
95 /// # Example
96 /// ```rust
97 /// # use const_serialize::ConstVec;
98 /// const EMPTY: ConstVec<u8> = ConstVec::new();
99 /// const ONE: ConstVec<u8> = EMPTY.push(1);
100 /// assert_eq!(ONE.as_ref(), &[1]);
101 /// ```
102 pub const fn push(mut self, value: T) -> Self {
103 self.memory[self.len as usize] = MaybeUninit::new(value);
104 self.len += 1;
105 self
106 }
107
108 /// Extend the [`ConstVec`] with the contents of a slice
109 ///
110 /// # Example
111 /// ```rust
112 /// # use const_serialize::ConstVec;
113 /// const EMPTY: ConstVec<u8> = ConstVec::new();
114 /// const ONE: ConstVec<u8> = EMPTY.extend(&[1, 2, 3]);
115 /// assert_eq!(ONE.as_ref(), &[1, 2, 3]);
116 /// ```
117 pub const fn extend(mut self, other: &[T]) -> Self
118 where
119 T: Copy,
120 {
121 let mut i = 0;
122 while i < other.len() {
123 self = self.push(other[i]);
124 i += 1;
125 }
126 self
127 }
128
129 /// Get a reference to the value at the given index
130 ///
131 /// # Example
132 /// ```rust
133 /// # use const_serialize::ConstVec;
134 /// const EMPTY: ConstVec<u8> = ConstVec::new();
135 /// const ONE: ConstVec<u8> = EMPTY.push(1);
136 /// assert_eq!(ONE.get(0), Some(&1));
137 /// ```
138 pub const fn get(&self, index: usize) -> Option<&T> {
139 if index < self.len as usize {
140 Some(unsafe { &*self.memory[index].as_ptr() })
141 } else {
142 None
143 }
144 }
145
146 /// Get the length of the [`ConstVec`]
147 ///
148 /// # Example
149 /// ```rust
150 /// # use const_serialize::ConstVec;
151 /// const EMPTY: ConstVec<u8> = ConstVec::new();
152 /// const ONE: ConstVec<u8> = EMPTY.push(1);
153 /// assert_eq!(ONE.len(), 1);
154 /// ```
155 pub const fn len(&self) -> usize {
156 self.len as usize
157 }
158
159 /// Check if the [`ConstVec`] is empty
160 ///
161 /// # Example
162 /// ```rust
163 /// # use const_serialize::ConstVec;
164 /// const EMPTY: ConstVec<u8> = ConstVec::new();
165 /// assert!(EMPTY.is_empty());
166 /// const ONE: ConstVec<u8> = EMPTY.push(1);
167 /// assert!(!ONE.is_empty());
168 /// ```
169 pub const fn is_empty(&self) -> bool {
170 self.len == 0
171 }
172
173 /// Get a reference to the underlying slice
174 ///
175 /// # Example
176 /// ```rust
177 /// # use const_serialize::ConstVec;
178 /// const EMPTY: ConstVec<u8> = ConstVec::new();
179 /// const ONE: ConstVec<u8> = EMPTY.push(1);
180 /// assert_eq!(ONE.as_ref(), &[1]);
181 /// ```
182 pub const fn as_ref(&self) -> &[T] {
183 unsafe {
184 &*(self.memory.split_at(self.len as usize).0 as *const [MaybeUninit<T>] as *const [T])
185 }
186 }
187
188 /// Swap the values at the given indices
189 ///
190 /// # Example
191 /// ```rust
192 /// # use const_serialize::ConstVec;
193 /// const EMPTY: ConstVec<u8> = ConstVec::new();
194 /// const ONE: ConstVec<u8> = EMPTY.push(1);
195 /// const TWO: ConstVec<u8> = ONE.push(2);
196 /// const THREE: ConstVec<u8> = TWO.swap(0, 1);
197 /// assert_eq!(THREE.as_ref(), &[2, 1]);
198 /// ```
199 pub const fn swap(mut self, first: usize, second: usize) -> Self
200 where
201 T: Copy,
202 {
203 assert!(first < self.len as usize);
204 assert!(second < self.len as usize);
205 let temp = self.memory[first];
206 self.memory[first] = self.memory[second];
207 self.memory[second] = temp;
208 self
209 }
210
211 /// Pop a value off the end of the [`ConstVec`]
212 ///
213 /// # Example
214 /// ```rust
215 /// # use const_serialize::ConstVec;
216 /// const EMPTY: ConstVec<u8> = ConstVec::new();
217 /// const ONE: ConstVec<u8> = EMPTY.push(1);
218 /// const TWO: ConstVec<u8> = ONE.push(2);
219 /// const THREE: ConstVec<u8> = TWO.push(3);
220 /// const POPPED: (ConstVec<u8>, Option<u8>) = THREE.pop();
221 /// assert_eq!(POPPED.0, TWO);
222 /// assert_eq!(POPPED.1.unwrap(), 3);
223 /// ```
224 pub const fn pop(mut self) -> (Self, Option<T>)
225 where
226 T: Copy,
227 {
228 let value = if self.len > 0 {
229 self.len -= 1;
230 let last = self.len as usize;
231 let last_value = unsafe { self.memory[last].assume_init() };
232 Some(last_value)
233 } else {
234 None
235 };
236 (self, value)
237 }
238
239 /// Remove the value at the given index
240 ///
241 /// # Example
242 /// ```rust
243 /// # use const_serialize::ConstVec;
244 /// const EMPTY: ConstVec<u8> = ConstVec::new();
245 /// const ONE: ConstVec<u8> = EMPTY.push(1);
246 /// const TWO: ConstVec<u8> = ONE.push(2);
247 /// const THREE: ConstVec<u8> = TWO.push(3);
248 /// const REMOVED: (ConstVec<u8>, Option<u8>) = THREE.remove(1);
249 /// assert_eq!(REMOVED.0.as_ref(), &[1, 3]);
250 /// assert_eq!(REMOVED.1.unwrap(), 2);
251 /// ```
252 pub const fn remove(mut self, index: usize) -> (Self, Option<T>)
253 where
254 T: Copy,
255 {
256 let value = if index < self.len as usize {
257 let value = unsafe { self.memory[index].assume_init() };
258 let mut swap_index = index;
259 while swap_index + 1 < self.len as usize {
260 self.memory[swap_index] = self.memory[swap_index + 1];
261 swap_index += 1;
262 }
263 self.len -= 1;
264 Some(value)
265 } else {
266 None
267 };
268
269 (self, value)
270 }
271
272 /// Set the value at the given index
273 ///
274 /// # Example
275 /// ```rust
276 /// # use const_serialize::ConstVec;
277 /// const EMPTY: ConstVec<u8> = ConstVec::new();
278 /// const ONE: ConstVec<u8> = EMPTY.push(1);
279 /// const TWO: ConstVec<u8> = ONE.set(0, 2);
280 /// assert_eq!(TWO.as_ref(), &[2]);
281 /// ```
282 pub const fn set(mut self, index: usize, value: T) -> Self {
283 if index >= self.len as usize {
284 panic!("Out of bounds")
285 }
286 self.memory[index] = MaybeUninit::new(value);
287 self
288 }
289
290 pub(crate) const fn into_parts(self) -> ([MaybeUninit<T>; MAX_SIZE], usize) {
291 (self.memory, self.len as usize)
292 }
293
294 /// Split the [`ConstVec`] into two at the given index
295 ///
296 /// # Example
297 /// ```rust
298 /// # use const_serialize::ConstVec;
299 /// const EMPTY: ConstVec<u8> = ConstVec::new();
300 /// const ONE: ConstVec<u8> = EMPTY.push(1);
301 /// const TWO: ConstVec<u8> = ONE.push(2);
302 /// const THREE: ConstVec<u8> = TWO.push(3);
303 /// const SPLIT: (ConstVec<u8>, ConstVec<u8>) = THREE.split_at(1);
304 /// assert_eq!(SPLIT.0.as_ref(), &[1]);
305 /// assert_eq!(SPLIT.1.as_ref(), &[2, 3]);
306 /// ```
307 pub const fn split_at(&self, index: usize) -> (Self, Self)
308 where
309 T: Copy,
310 {
311 assert!(index <= self.len as usize);
312 let slice = self.as_ref();
313 let (left, right) = slice.split_at(index);
314 let mut left_vec = Self::new_with_max_size();
315 let mut i = 0;
316 while i < left.len() {
317 left_vec = left_vec.push(left[i]);
318 i += 1;
319 }
320 let mut right_vec = Self::new_with_max_size();
321 i = 0;
322 while i < right.len() {
323 right_vec = right_vec.push(right[i]);
324 i += 1;
325 }
326 (left_vec, right_vec)
327 }
328}
329
330impl<const MAX_SIZE: usize> ConstVec<u8, MAX_SIZE> {
331 /// Convert the [`ConstVec`] into a [`ConstReadBuffer`](crate::ConstReadBuffer)
332 ///
333 /// # Example
334 /// ```rust
335 /// # use const_serialize::{ConstVec, ConstReadBuffer};
336 /// const EMPTY: ConstVec<u8> = ConstVec::new();
337 /// const ONE: ConstVec<u8> = EMPTY.push(1);
338 /// const TWO: ConstVec<u8> = ONE.push(2);
339 /// const READ: ConstReadBuffer = TWO.read();
340 /// ```
341 pub const fn read(&self) -> ConstReadBuffer<'_> {
342 ConstReadBuffer::new(self.as_ref())
343 }
344}
345
346#[test]
347fn test_const_vec() {
348 const VEC: ConstVec<u32> = {
349 let mut vec = ConstVec::new();
350 vec = vec.push(1234);
351 vec = vec.push(5678);
352 vec
353 };
354 assert_eq!(VEC.as_ref(), &[1234, 5678]);
355 let vec = VEC;
356 let (vec, value) = vec.pop();
357 assert_eq!(value, Some(5678));
358 let (vec, value) = vec.pop();
359 assert_eq!(value, Some(1234));
360 let (vec, value) = vec.pop();
361 assert_eq!(value, None);
362 assert_eq!(vec.as_ref(), &[]);
363}
364
365#[test]
366fn test_const_vec_len() {
367 const VEC: ConstVec<u32> = {
368 let mut vec = ConstVec::new();
369 vec = vec.push(1234);
370 vec = vec.push(5678);
371 vec
372 };
373 assert_eq!(VEC.len(), 2);
374}
375
376#[test]
377fn test_const_vec_get() {
378 const VEC: ConstVec<u32> = {
379 let mut vec = ConstVec::new();
380 vec = vec.push(1234);
381 vec = vec.push(5678);
382 vec
383 };
384 assert_eq!(VEC.get(0), Some(&1234));
385 assert_eq!(VEC.get(1), Some(&5678));
386 assert_eq!(VEC.get(2), None);
387}
388
389#[test]
390fn test_const_vec_swap() {
391 const VEC: ConstVec<u32> = {
392 let mut vec = ConstVec::new();
393 vec = vec.push(1234);
394 vec = vec.push(5678);
395 vec
396 };
397 let mut vec = VEC;
398 assert_eq!(vec.as_ref(), &[1234, 5678]);
399 vec = vec.swap(0, 1);
400 assert_eq!(vec.as_ref(), &[5678, 1234]);
401 vec = vec.swap(0, 1);
402 assert_eq!(vec.as_ref(), &[1234, 5678]);
403}
404
405#[test]
406fn test_const_vec_remove() {
407 const VEC: ConstVec<u32> = {
408 let mut vec = ConstVec::new();
409 vec = vec.push(1234);
410 vec = vec.push(5678);
411 vec
412 };
413 let vec = VEC;
414 println!("{:?}", vec);
415 assert_eq!(vec.as_ref(), &[1234, 5678]);
416 let (vec, value) = vec.remove(0);
417 assert_eq!(value, Some(1234));
418 assert_eq!(vec.as_ref(), &[5678]);
419 let (vec, value) = vec.remove(0);
420 assert_eq!(value, Some(5678));
421 assert_eq!(vec.as_ref(), &[]);
422}