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    /// Try to convert this [`ArrayVec`] into a `[T; N]`.
70    ///
71    /// Returns `None` if the [`ArrayVec`] does not contain `N` elements.
72    pub fn try_into_array(self) -> Result<[T; N]> {
73        if self.length != N {
74            return Err(ErrorKind::Incomplete {
75                expected_len: N.try_into()?,
76                actual_len: self.length.try_into()?,
77            }
78            .into());
79        }
80
81        Ok(self.elements.map(|elem| match elem {
82            Some(e) => e,
83            None => unreachable!(),
84        }))
85    }
86}
87
88impl<T, const N: usize> Default for ArrayVec<T, N> {
89    fn default() -> Self {
90        Self::new()
91    }
92}
93
94/// Iterator over the elements of an [`ArrayVec`].
95#[derive(Clone, Debug)]
96pub struct Iter<'a, T> {
97    /// Decoder which iterates over the elements of the message.
98    elements: &'a [Option<T>],
99
100    /// Position within the iterator.
101    position: usize,
102}
103
104impl<'a, T> Iter<'a, T> {
105    pub(crate) fn new(elements: &'a [Option<T>]) -> Self {
106        Self {
107            elements,
108            position: 0,
109        }
110    }
111}
112
113impl<'a, T> Iterator for Iter<'a, T> {
114    type Item = &'a T;
115
116    fn next(&mut self) -> Option<&'a T> {
117        if let Some(Some(res)) = self.elements.get(self.position) {
118            self.position = self.position.checked_add(1)?;
119            Some(res)
120        } else {
121            None
122        }
123    }
124}