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}