utils/
array.rs

1//! Array helpers.
2
3use std::fmt;
4use std::hash::Hash;
5use std::ops::{Deref, DerefMut};
6
7/// A fixed-size array-backed vector.
8///
9/// `ArrayVec` has a fixed-sized `N` long array and a length field to track how many elements are
10/// populated. It is useful for storing a small but variable number of elements without heap
11/// allocation.
12///
13/// The implementation is intentionally simple, and requires [`Copy`] and [`Default`] bounds on some
14/// methods instead of using [`std::mem::MaybeUninit`].
15#[derive(Clone, PartialEq, Eq, Hash)]
16pub struct ArrayVec<T, const N: usize> {
17    len: usize,
18    data: [T; N],
19}
20
21impl<T, const N: usize> ArrayVec<T, N> {
22    /// Creates a new empty `ArrayVec`.
23    ///
24    /// # Examples
25    /// ```
26    /// # use utils::array::ArrayVec;
27    /// let vec: ArrayVec<i32, 5> = ArrayVec::new();
28    /// assert_eq!(vec.len(), 0);
29    /// ```
30    #[inline]
31    #[must_use]
32    pub fn new() -> Self
33    where
34        T: Copy + Default,
35    {
36        Self {
37            len: 0,
38            data: [T::default(); N],
39        }
40    }
41
42    /// Creates a new `ArrayVec`, copying initial data from the provided slice.
43    ///
44    /// # Examples
45    /// ```
46    /// # use utils::array::ArrayVec;
47    /// let mut vec: ArrayVec<i32, 5> = ArrayVec::<i32, 5>::from_slice(&[1, 2, 3]).unwrap();
48    /// assert_eq!(vec.len(), 3);
49    /// assert_eq!(vec.pop(), Some(3));
50    /// assert_eq!(vec.pop(), Some(2));
51    /// assert_eq!(vec.pop(), Some(1));
52    /// assert_eq!(vec.pop(), None);
53    ///
54    /// assert_eq!(ArrayVec::<i32, 5>::from_slice(&[1, 2, 3, 4, 5, 6]), None);
55    /// ```
56    #[inline]
57    #[must_use]
58    pub fn from_slice(slice: &[T]) -> Option<Self>
59    where
60        T: Copy + Default,
61    {
62        if slice.len() > N {
63            None
64        } else {
65            let mut data = [T::default(); N];
66            data[..slice.len()].copy_from_slice(slice);
67            Some(Self {
68                len: slice.len(),
69                data,
70            })
71        }
72    }
73
74    /// Adds an element to the end of the vector.
75    ///
76    /// Returns [`Err`] containing the provided value if the vector is already full.
77    ///
78    /// # Examples
79    /// ```
80    /// # use utils::array::ArrayVec;
81    /// let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
82    /// assert_eq!(vec.push(1), Ok(()));
83    /// assert_eq!(vec.push(2), Ok(()));
84    /// assert_eq!(vec.push(3), Err(3)); // Vector is full
85    /// ```
86    #[inline]
87    pub fn push(&mut self, value: T) -> Result<(), T> {
88        if self.len < N {
89            self.data[self.len] = value;
90            self.len += 1;
91            Ok(())
92        } else {
93            Err(value)
94        }
95    }
96
97    /// Removes the last element from the vector and returns it, or [`None`] if it is empty.
98    ///
99    /// # Examples
100    /// ```
101    /// # use utils::array::ArrayVec;
102    /// let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
103    /// vec.push(1).unwrap();
104    /// assert_eq!(vec.pop(), Some(1));
105    /// assert_eq!(vec.pop(), None);
106    /// ```
107    #[inline]
108    pub fn pop(&mut self) -> Option<T>
109    where
110        T: Default,
111    {
112        if self.len > 0 {
113            self.len -= 1;
114            Some(std::mem::take(&mut self.data[self.len]))
115        } else {
116            None
117        }
118    }
119
120    /// Returns a slice of all the populated elements in the vector.
121    ///
122    /// # Examples
123    ///
124    /// ```
125    /// # use utils::array::ArrayVec;
126    /// let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
127    /// vec.push(1).unwrap();
128    /// vec.push(2).unwrap();
129    /// assert_eq!(vec.as_slice(), &[1, 2]);
130    /// ```
131    #[inline]
132    pub fn as_slice(&self) -> &[T] {
133        #[cfg(feature = "unsafe")]
134        unsafe {
135            std::hint::assert_unchecked(self.len <= N);
136        }
137
138        &self.data[..self.len]
139    }
140
141    /// Returns a mutable slice of all the populated elements in the vector.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// # use utils::array::ArrayVec;
147    /// let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
148    /// vec.push(1).unwrap();
149    /// vec.push(2).unwrap();
150    /// let mut slice = vec.as_mut_slice();
151    /// slice[1] = 10;
152    /// assert_eq!(slice, &[1, 10]);
153    /// ```
154    #[inline]
155    pub fn as_mut_slice(&mut self) -> &mut [T] {
156        #[cfg(feature = "unsafe")]
157        unsafe {
158            std::hint::assert_unchecked(self.len <= N);
159        }
160
161        &mut self.data[..self.len]
162    }
163
164    /// Returns a reference to the backing array.
165    ///
166    /// Any items after the current length will be set to the default value.
167    ///
168    /// # Examples
169    /// ```
170    /// # use utils::array::ArrayVec;
171    /// let mut vec: ArrayVec<i32, 8> = ArrayVec::new();
172    /// vec.push(10).unwrap();
173    /// vec.push(6).unwrap();
174    /// vec.pop().unwrap();
175    /// assert_eq!(vec.into_array(), [10, 0, 0, 0, 0, 0, 0, 0]);
176    /// ```
177    #[inline]
178    pub fn as_array(&self) -> &[T; N] {
179        &self.data
180    }
181
182    /// Returns the capacity of the vector, which is always `N`.
183    ///
184    /// # Examples
185    /// ```
186    /// # use utils::array::ArrayVec;
187    /// let vec: ArrayVec<i32, 5> = ArrayVec::new();
188    /// assert_eq!(vec.capacity(), 5);
189    /// ```
190    #[inline]
191    pub fn capacity(&self) -> usize {
192        N
193    }
194
195    /// Returns whether the vector is full.
196    ///
197    /// # Examples
198    ///
199    /// ```
200    /// # use utils::array::ArrayVec;
201    /// let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
202    /// assert!(!vec.is_full());
203    /// vec.push(1).unwrap();
204    /// assert!(!vec.is_full());
205    /// vec.push(2).unwrap();
206    /// assert!(vec.is_full());
207    /// ```
208    #[inline]
209    pub fn is_full(&self) -> bool {
210        self.len == N
211    }
212
213    /// Returns the backing array.
214    ///
215    /// Any items after the current length will be set to the default value.
216    ///
217    /// # Examples
218    /// ```
219    /// # use utils::array::ArrayVec;
220    /// let mut vec: ArrayVec<i32, 5> = ArrayVec::new();
221    /// vec.push(1).unwrap();
222    /// vec.push(2).unwrap();
223    /// vec.push(3).unwrap();
224    /// vec.pop().unwrap();
225    /// assert_eq!(vec.into_array(), [1, 2, 0, 0, 0]);
226    /// ```
227    #[inline]
228    pub fn into_array(self) -> [T; N] {
229        self.data
230    }
231}
232
233impl<T, const N: usize> Deref for ArrayVec<T, N> {
234    type Target = [T];
235
236    #[inline]
237    fn deref(&self) -> &Self::Target {
238        self.as_slice()
239    }
240}
241
242impl<T, const N: usize> DerefMut for ArrayVec<T, N> {
243    #[inline]
244    fn deref_mut(&mut self) -> &mut Self::Target {
245        self.as_mut_slice()
246    }
247}
248
249impl<'a, T, const N: usize> IntoIterator for &'a ArrayVec<T, N> {
250    type Item = &'a T;
251    type IntoIter = std::slice::Iter<'a, T>;
252
253    #[inline]
254    fn into_iter(self) -> Self::IntoIter {
255        self.iter()
256    }
257}
258
259impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayVec<T, N> {
260    type Item = &'a mut T;
261    type IntoIter = std::slice::IterMut<'a, T>;
262
263    #[inline]
264    fn into_iter(self) -> Self::IntoIter {
265        self.iter_mut()
266    }
267}
268
269impl<T: fmt::Debug, const N: usize> fmt::Debug for ArrayVec<T, N> {
270    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271        f.debug_struct("ArrayVec")
272            .field("len", &self.len)
273            .field("cap", &N)
274            .field("data", &self.as_slice())
275            .finish()
276    }
277}
278
279impl<T: Default + Copy, const N: usize> Default for ArrayVec<T, N> {
280    fn default() -> Self {
281        Self::new()
282    }
283}
284
285impl<T, const N: usize> From<[T; N]> for ArrayVec<T, N> {
286    fn from(data: [T; N]) -> Self {
287        ArrayVec { len: N, data }
288    }
289}