der/
arrayvec.rs

1//! Array-backed append-only vector type.
2// TODO(tarcieri): use `core` impl of `ArrayVec`
3// See: https://github.com/rust-lang/rfcs/pull/2990
4
5use crate::{ErrorKind, Result};
6
7/// Array-backed append-only vector type.
8#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
9pub(crate) struct ArrayVec<T, const N: usize> {
10    /// Elements of the set.
11    elements: [Option<T>; N],
12
13    /// Last populated element.
14    length: usize,
15}
16
17impl<T, const N: usize> ArrayVec<T, N> {
18    /// Create a new [`ArrayVec`].
19    pub fn new() -> Self {
20        Self {
21            elements: [(); N].map(|_| None),
22            length: 0,
23        }
24    }
25
26    /// Add an element to this [`ArrayVec`].
27    ///
28    /// Items MUST be added in lexicographical order according to the `Ord`
29    /// impl on `T`.
30    pub fn add(&mut self, element: T) -> Result<()> {
31        match self.length.checked_add(1) {
32            Some(n) if n <= N => {
33                self.elements[self.length] = Some(element);
34                self.length = n;
35                Ok(())
36            }
37            _ => Err(ErrorKind::Overlength.into()),
38        }
39    }
40
41    /// Get an element from this [`ArrayVec`].
42    pub fn get(&self, index: usize) -> Option<&T> {
43        match self.elements.get(index) {
44            Some(Some(ref item)) => Some(item),
45            _ => None,
46        }
47    }
48
49    /// Iterate over the elements in this [`ArrayVec`].
50    pub fn iter(&self) -> Iter<'_, T> {
51        Iter::new(&self.elements)
52    }
53
54    /// Is this [`ArrayVec`] empty?
55    pub fn is_empty(&self) -> bool {
56        self.length == 0
57    }
58
59    /// Get the number of elements in this [`ArrayVec`].
60    pub fn len(&self) -> usize {
61        self.length
62    }
63
64    /// Get the last item from this [`ArrayVec`].
65    pub fn last(&self) -> Option<&T> {
66        self.length.checked_sub(1).and_then(|n| self.get(n))
67    }
68
69    /// Extract the inner array.
70    pub fn into_array(self) -> [Option<T>; N] {
71        self.elements
72    }
73}
74
75impl<T, const N: usize> AsRef<[Option<T>]> for ArrayVec<T, N> {
76    fn as_ref(&self) -> &[Option<T>] {
77        &self.elements[..self.length]
78    }
79}
80
81impl<T, const N: usize> AsMut<[Option<T>]> for ArrayVec<T, N> {
82    fn as_mut(&mut self) -> &mut [Option<T>] {
83        &mut self.elements[..self.length]
84    }
85}
86
87impl<T, const N: usize> Default for ArrayVec<T, N> {
88    fn default() -> Self {
89        Self::new()
90    }
91}
92
93/// Iterator over the elements of an [`ArrayVec`].
94#[derive(Clone, Debug)]
95pub struct Iter<'a, T> {
96    /// Decoder which iterates over the elements of the message.
97    elements: &'a [Option<T>],
98
99    /// Position within the iterator.
100    position: usize,
101}
102
103impl<'a, T> Iter<'a, T> {
104    pub(crate) fn new(elements: &'a [Option<T>]) -> Self {
105        Self {
106            elements,
107            position: 0,
108        }
109    }
110}
111
112impl<'a, T> Iterator for Iter<'a, T> {
113    type Item = &'a T;
114
115    fn next(&mut self) -> Option<&'a T> {
116        match self.elements.get(self.position) {
117            Some(Some(res)) => {
118                self.position = self.position.checked_add(1)?;
119                Some(res)
120            }
121            _ => None,
122        }
123    }
124
125    fn size_hint(&self) -> (usize, Option<usize>) {
126        let len = self.elements.len().saturating_sub(self.position);
127        (len, Some(len))
128    }
129}
130
131impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
132
133#[cfg(test)]
134mod tests {
135    use super::ArrayVec;
136    use crate::ErrorKind;
137
138    #[test]
139    fn add() {
140        let mut vec = ArrayVec::<u8, 3>::new();
141        vec.add(1).unwrap();
142        vec.add(2).unwrap();
143        vec.add(3).unwrap();
144
145        assert_eq!(vec.add(4).err().unwrap(), ErrorKind::Overlength.into());
146        assert_eq!(vec.len(), 3);
147    }
148}