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 the capacity of the vector, which is always `N`.
165    ///
166    /// # Examples
167    /// ```
168    /// # use utils::array::ArrayVec;
169    /// let vec: ArrayVec<i32, 5> = ArrayVec::new();
170    /// assert_eq!(vec.capacity(), 5);
171    /// ```
172    #[inline]
173    pub fn capacity(&self) -> usize {
174        N
175    }
176
177    /// Returns whether the vector is full.
178    ///
179    /// # Examples
180    ///
181    /// ```
182    /// # use utils::array::ArrayVec;
183    /// let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
184    /// assert!(!vec.is_full());
185    /// vec.push(1).unwrap();
186    /// assert!(!vec.is_full());
187    /// vec.push(2).unwrap();
188    /// assert!(vec.is_full());
189    /// ```
190    #[inline]
191    pub fn is_full(&self) -> bool {
192        self.len == N
193    }
194
195    /// Returns the backing array.
196    ///
197    /// Any items after the current length will be set to the default value.
198    ///
199    /// # Examples
200    /// ```
201    /// # use utils::array::ArrayVec;
202    /// let mut vec: ArrayVec<i32, 5> = ArrayVec::new();
203    /// vec.push(1).unwrap();
204    /// vec.push(2).unwrap();
205    /// vec.push(3).unwrap();
206    /// vec.pop().unwrap();
207    /// assert_eq!(vec.into_array(), [1, 2, 0, 0, 0]);
208    /// ```
209    #[inline]
210    pub fn into_array(self) -> [T; N] {
211        self.data
212    }
213}
214
215impl<T, const N: usize> Deref for ArrayVec<T, N> {
216    type Target = [T];
217
218    #[inline]
219    fn deref(&self) -> &Self::Target {
220        self.as_slice()
221    }
222}
223
224impl<T, const N: usize> DerefMut for ArrayVec<T, N> {
225    #[inline]
226    fn deref_mut(&mut self) -> &mut Self::Target {
227        self.as_mut_slice()
228    }
229}
230
231impl<'a, T, const N: usize> IntoIterator for &'a ArrayVec<T, N> {
232    type Item = &'a T;
233    type IntoIter = std::slice::Iter<'a, T>;
234
235    #[inline]
236    fn into_iter(self) -> Self::IntoIter {
237        self.iter()
238    }
239}
240
241impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayVec<T, N> {
242    type Item = &'a mut T;
243    type IntoIter = std::slice::IterMut<'a, T>;
244
245    #[inline]
246    fn into_iter(self) -> Self::IntoIter {
247        self.iter_mut()
248    }
249}
250
251impl<T: fmt::Debug, const N: usize> fmt::Debug for ArrayVec<T, N> {
252    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253        f.debug_struct("ArrayVec")
254            .field("len", &self.len)
255            .field("cap", &N)
256            .field("data", &self.as_slice())
257            .finish()
258    }
259}
260
261impl<T: Default + Copy, const N: usize> Default for ArrayVec<T, N> {
262    fn default() -> Self {
263        Self::new()
264    }
265}
266
267impl<T, const N: usize> From<[T; N]> for ArrayVec<T, N> {
268    fn from(data: [T; N]) -> Self {
269        ArrayVec { len: N, data }
270    }
271}