summaryrefslogtreecommitdiffstats
path: root/vendor/der/src/arrayvec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/der/src/arrayvec.rs')
-rw-r--r--vendor/der/src/arrayvec.rs148
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);
+ }
+}