1#[cfg(feature = "alloc")]
4extern crate alloc;
5
6use core::{hash, iter::FromIterator, slice};
7
8use crate::error::{Error, Result};
9
10#[cfg(feature = "alloc")]
11type Inner<T, const N: usize> = alloc::vec::Vec<T>;
12#[cfg(not(feature = "alloc"))]
13type Inner<T, const N: usize> = heapless::Vec<T, N>;
14
15#[derive(Clone, Debug)]
23pub struct Vec<T, const N: usize>(Inner<T, N>);
24
25impl<T, const N: usize> Vec<T, N> {
26 #[inline]
28 pub fn new() -> Self {
29 Self::default()
30 }
31
32 #[inline]
34 pub fn from_slice(other: &[T]) -> Result<Self>
35 where
36 T: Clone,
37 {
38 #[cfg(feature = "alloc")]
39 {
40 if other.len() > N {
41 return Err(Error::CapacityExceeded);
42 }
43 let mut v = Self(Inner::with_capacity(other.len()));
44 v.0.extend_from_slice(other);
45 Ok(v)
46 }
47 #[cfg(not(feature = "alloc"))]
48 {
49 let mut v = Self::new();
50 v.extend_from_slice(other)?;
51 Ok(v)
52 }
53 }
54
55 #[inline]
57 pub fn as_slice(&self) -> &[T] {
58 &self.0
59 }
60
61 #[inline]
63 pub fn as_mut_slice(&mut self) -> &mut [T] {
64 &mut self.0
65 }
66
67 #[inline]
69 pub fn len(&self) -> usize {
70 self.0.len()
71 }
72
73 #[inline]
75 pub fn is_empty(&self) -> bool {
76 self.0.is_empty()
77 }
78
79 #[inline]
81 pub fn clear(&mut self) {
82 self.0.clear();
83 }
84
85 #[inline]
87 pub fn extend_from_slice(&mut self, other: &[T]) -> Result<()>
88 where
89 T: Clone,
90 {
91 #[cfg(feature = "alloc")]
92 {
93 let current_len = self.0.len();
94 let new_len = current_len.saturating_add(other.len());
95 if new_len > N {
96 return Err(Error::CapacityExceeded);
97 }
98 let current_cap = self.0.capacity();
99 if current_cap < new_len {
100 self.0.reserve_exact(new_len - current_cap);
101 }
102 self.0.extend_from_slice(other);
103 Ok(())
104 }
105 #[cfg(not(feature = "alloc"))]
106 {
107 self.0
108 .extend_from_slice(other)
109 .map_err(|_| Error::CapacityExceeded)
110 }
111 }
112
113 #[inline]
115 pub fn push(&mut self, item: T) -> Result<()> {
116 #[cfg(feature = "alloc")]
117 {
118 if self.0.len() >= N {
119 return Err(Error::CapacityExceeded);
120 }
121 self.0.push(item);
122 Ok(())
123 }
124 #[cfg(not(feature = "alloc"))]
125 {
126 self.0.push(item).map_err(|_| Error::CapacityExceeded)
127 }
128 }
129
130 #[inline]
132 pub fn get(&self, index: usize) -> Option<&T> {
133 self.0.get(index)
134 }
135
136 #[inline]
138 pub fn iter(&self) -> slice::Iter<'_, T> {
139 self.0.iter()
140 }
141
142 #[inline]
144 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
145 self.0.iter_mut()
146 }
147
148 #[inline]
150 #[cfg(not(feature = "alloc"))]
151 pub(crate) fn into_inner(self) -> Inner<T, N> {
152 self.0
153 }
154}
155
156impl<'a, T, const N: usize> IntoIterator for &'a Vec<T, N> {
157 type Item = &'a T;
158 type IntoIter = slice::Iter<'a, T>;
159
160 #[inline]
161 fn into_iter(self) -> Self::IntoIter {
162 self.iter()
163 }
164}
165
166#[cfg(feature = "alloc")]
167impl<T, const N: usize> IntoIterator for Vec<T, N> {
168 type Item = T;
169 type IntoIter = alloc::vec::IntoIter<T>;
170
171 #[inline]
172 fn into_iter(self) -> Self::IntoIter {
173 self.0.into_iter()
174 }
175}
176
177#[cfg(not(feature = "alloc"))]
178impl<T, const N: usize> IntoIterator for Vec<T, N> {
179 type Item = T;
180 type IntoIter = heapless::vec::IntoIter<T, N, usize>;
181
182 #[inline]
183 fn into_iter(self) -> Self::IntoIter {
184 self.0.into_iter()
185 }
186}
187
188impl<T, const N: usize> FromIterator<T> for Vec<T, N> {
189 fn from_iter<I>(iter: I) -> Self
190 where
191 I: IntoIterator<Item = T>,
192 {
193 #[cfg(feature = "alloc")]
194 {
195 let iter = iter.into_iter();
196 let (lower, upper) = iter.size_hint();
197 let reserve = upper.unwrap_or(lower).min(N);
198 let mut v = alloc::vec::Vec::new();
199 if reserve > 0 {
200 v.reserve_exact(reserve);
201 }
202 for item in iter {
203 if v.len() >= N {
204 panic!("Vec::from_iter overflow");
205 }
206 v.push(item);
207 }
208 Self(v)
209 }
210 #[cfg(not(feature = "alloc"))]
211 {
212 Self(Inner::from_iter(iter))
213 }
214 }
215}
216
217impl<T, const N: usize> hash::Hash for Vec<T, N>
218where
219 T: hash::Hash,
220{
221 #[inline]
222 fn hash<H: hash::Hasher>(&self, state: &mut H) {
223 self.0.hash(state);
224 }
225}
226
227impl<T, const N: usize> PartialEq for Vec<T, N>
228where
229 T: PartialEq,
230{
231 #[inline]
232 fn eq(&self, other: &Self) -> bool {
233 self.0 == other.0
234 }
235}
236
237impl<T, const N: usize> Eq for Vec<T, N> where T: Eq {}
238
239impl<T, const N: usize> Default for Vec<T, N> {
240 #[inline]
241 fn default() -> Self {
242 #[cfg(feature = "alloc")]
243 {
244 Self(Inner::with_capacity(N))
245 }
246 #[cfg(not(feature = "alloc"))]
247 {
248 Self(Inner::new())
249 }
250 }
251}
252
253impl<T, const N: usize> core::ops::Index<usize> for Vec<T, N> {
254 type Output = T;
255
256 #[inline]
257 fn index(&self, index: usize) -> &Self::Output {
258 &self.0[index]
259 }
260}
261
262impl<T, const N: usize> core::ops::Deref for Vec<T, N> {
263 type Target = [T];
264
265 #[inline]
266 fn deref(&self) -> &Self::Target {
267 self.as_slice()
268 }
269}
270
271#[cfg(all(test, feature = "alloc"))]
272mod from_iter_tests {
273 use super::Vec;
274
275 #[test]
276 fn from_iter_collects_up_to_n() {
277 let v: Vec<u8, 4> = [1, 2, 3, 4].into_iter().collect();
278 assert_eq!(v.as_slice(), [1, 2, 3, 4]);
279 }
280
281 #[test]
282 #[should_panic(expected = "Vec::from_iter overflow")]
283 fn from_iter_panics_when_more_than_n() {
284 let _: Vec<u8, 2> = [1_u8, 2, 3].into_iter().collect();
285 }
286
287 #[test]
288 #[should_panic(expected = "Vec::from_iter overflow")]
289 fn from_iter_panics_despite_lying_upper_hint() {
290 struct BadHint<I>(I);
291 impl<I: Iterator<Item = u8>> Iterator for BadHint<I> {
292 type Item = u8;
293 fn next(&mut self) -> Option<Self::Item> {
294 self.0.next()
295 }
296 fn size_hint(&self) -> (usize, Option<usize>) {
297 (0, Some(1))
298 }
299 }
300 let _: Vec<u8, 2> = BadHint([1_u8, 2, 3].into_iter()).collect();
301 }
302}