diff options
Diffstat (limited to 'vendor/der/src/arrayvec.rs')
-rw-r--r-- | vendor/der/src/arrayvec.rs | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/vendor/der/src/arrayvec.rs b/vendor/der/src/arrayvec.rs new file mode 100644 index 000000000..21f134196 --- /dev/null +++ b/vendor/der/src/arrayvec.rs @@ -0,0 +1,148 @@ +//! Array-backed append-only vector type. +// TODO(tarcieri): use `core` impl of `ArrayVec` +// See: https://github.com/rust-lang/rfcs/pull/2990 + +use crate::{ErrorKind, Result}; + +/// Array-backed append-only vector type. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub(crate) struct ArrayVec<T, const N: usize> { + /// Elements of the set. + elements: [Option<T>; N], + + /// Last populated element. + length: usize, +} + +impl<T, const N: usize> ArrayVec<T, N> { + /// Create a new [`ArrayVec`]. + pub fn new() -> Self { + Self { + elements: [(); N].map(|_| None), + length: 0, + } + } + + /// Add an element to this [`ArrayVec`]. + /// + /// Items MUST be added in lexicographical order according to the `Ord` + /// impl on `T`. + pub fn add(&mut self, element: T) -> Result<()> { + match self.length.checked_add(1) { + Some(n) if n <= N => { + self.elements[self.length] = Some(element); + self.length = n; + Ok(()) + } + _ => Err(ErrorKind::Overlength.into()), + } + } + + /// Get an element from this [`ArrayVec`]. + pub fn get(&self, index: usize) -> Option<&T> { + match self.elements.get(index) { + Some(Some(ref item)) => Some(item), + _ => None, + } + } + + /// Iterate over the elements in this [`ArrayVec`]. + pub fn iter(&self) -> Iter<'_, T> { + Iter::new(&self.elements) + } + + /// Is this [`ArrayVec`] empty? + pub fn is_empty(&self) -> bool { + self.length == 0 + } + + /// Get the number of elements in this [`ArrayVec`]. + pub fn len(&self) -> usize { + self.length + } + + /// Get the last item from this [`ArrayVec`]. + pub fn last(&self) -> Option<&T> { + self.length.checked_sub(1).and_then(|n| self.get(n)) + } + + /// Extract the inner array. + pub fn into_array(self) -> [Option<T>; N] { + self.elements + } +} + +impl<T, const N: usize> AsRef<[Option<T>]> for ArrayVec<T, N> { + fn as_ref(&self) -> &[Option<T>] { + &self.elements[..self.length] + } +} + +impl<T, const N: usize> AsMut<[Option<T>]> for ArrayVec<T, N> { + fn as_mut(&mut self) -> &mut [Option<T>] { + &mut self.elements[..self.length] + } +} + +impl<T, const N: usize> Default for ArrayVec<T, N> { + fn default() -> Self { + Self::new() + } +} + +/// Iterator over the elements of an [`ArrayVec`]. +#[derive(Clone, Debug)] +pub struct Iter<'a, T> { + /// Decoder which iterates over the elements of the message. + elements: &'a [Option<T>], + + /// Position within the iterator. + position: usize, +} + +impl<'a, T> Iter<'a, T> { + pub(crate) fn new(elements: &'a [Option<T>]) -> Self { + Self { + elements, + position: 0, + } + } +} + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { + match self.elements.get(self.position) { + Some(Some(res)) => { + self.position = self.position.checked_add(1)?; + Some(res) + } + _ => None, + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + let len = self.elements.len().saturating_sub(self.position); + (len, Some(len)) + } +} + +impl<'a, T> ExactSizeIterator for Iter<'a, T> {} + +#[cfg(test)] +mod tests { + use super::ArrayVec; + use crate::ErrorKind; + + #[test] + fn add() { + let mut vec = ArrayVec::<u8, 3>::new(); + vec.add(1).unwrap(); + vec.add(2).unwrap(); + vec.add(3).unwrap(); + + assert_eq!(vec.add(4).err().unwrap(), ErrorKind::Overlength.into()); + assert_eq!(vec.len(), 3); + } +} |