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