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.extend_from_slice(other).map_err(|_| Error::CapacityExceeded)
108 }
109 }
110
111 #[inline]
113 pub fn push(&mut self, item: T) -> Result<()> {
114 #[cfg(feature = "alloc")]
115 {
116 if self.0.len() >= N {
117 return Err(Error::CapacityExceeded);
118 }
119 self.0.push(item);
120 Ok(())
121 }
122 #[cfg(not(feature = "alloc"))]
123 {
124 self.0.push(item).map_err(|_| Error::CapacityExceeded)
125 }
126 }
127
128 #[inline]
130 pub fn get(&self, index: usize) -> Option<&T> {
131 self.0.get(index)
132 }
133
134 #[inline]
136 pub fn iter(&self) -> slice::Iter<'_, T> {
137 self.0.iter()
138 }
139
140 #[inline]
142 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
143 self.0.iter_mut()
144 }
145
146 #[inline]
148 #[cfg(not(feature = "alloc"))]
149 pub(crate) fn into_inner(self) -> Inner<T, N> {
150 self.0
151 }
152}
153
154impl<'a, T, const N: usize> IntoIterator for &'a Vec<T, N> {
155 type Item = &'a T;
156 type IntoIter = slice::Iter<'a, T>;
157
158 #[inline]
159 fn into_iter(self) -> Self::IntoIter {
160 self.iter()
161 }
162}
163
164#[cfg(feature = "alloc")]
165impl<T, const N: usize> IntoIterator for Vec<T, N> {
166 type Item = T;
167 type IntoIter = alloc::vec::IntoIter<T>;
168
169 #[inline]
170 fn into_iter(self) -> Self::IntoIter {
171 self.0.into_iter()
172 }
173}
174
175#[cfg(not(feature = "alloc"))]
176impl<T, const N: usize> IntoIterator for Vec<T, N> {
177 type Item = T;
178 type IntoIter = heapless::vec::IntoIter<T, N, usize>;
179
180 #[inline]
181 fn into_iter(self) -> Self::IntoIter {
182 self.0.into_iter()
183 }
184}
185
186impl<T, const N: usize> FromIterator<T> for Vec<T, N> {
187 fn from_iter<I>(iter: I) -> Self
188 where
189 I: IntoIterator<Item = T>,
190 {
191 #[cfg(feature = "alloc")]
192 {
193 let iter = iter.into_iter();
194 let (lower, upper) = iter.size_hint();
195 let reserve = upper.unwrap_or(lower).min(N);
196 let mut v = alloc::vec::Vec::new();
197 if reserve > 0 {
198 v.reserve_exact(reserve);
199 }
200 for item in iter {
201 if v.len() >= N {
202 panic!("Vec::from_iter overflow");
203 }
204 v.push(item);
205 }
206 Self(v)
207 }
208 #[cfg(not(feature = "alloc"))]
209 {
210 Self(Inner::from_iter(iter))
211 }
212 }
213}
214
215impl<T, const N: usize> hash::Hash for Vec<T, N>
216where
217 T: hash::Hash,
218{
219 #[inline]
220 fn hash<H: hash::Hasher>(&self, state: &mut H) {
221 self.0.hash(state);
222 }
223}
224
225impl<T, const N: usize> PartialEq for Vec<T, N>
226where
227 T: PartialEq,
228{
229 #[inline]
230 fn eq(&self, other: &Self) -> bool {
231 self.0 == other.0
232 }
233}
234
235impl<T, const N: usize> Eq for Vec<T, N> where T: Eq {}
236
237impl<T, const N: usize> Default for Vec<T, N> {
238 #[inline]
239 fn default() -> Self {
240 #[cfg(feature = "alloc")]
241 {
242 Self(Inner::with_capacity(N))
243 }
244 #[cfg(not(feature = "alloc"))]
245 {
246 Self(Inner::new())
247 }
248 }
249}
250
251impl<T, const N: usize> core::ops::Index<usize> for Vec<T, N> {
252 type Output = T;
253
254 #[inline]
255 fn index(&self, index: usize) -> &Self::Output {
256 &self.0[index]
257 }
258}
259
260impl<T, const N: usize> core::ops::Deref for Vec<T, N> {
261 type Target = [T];
262
263 #[inline]
264 fn deref(&self) -> &Self::Target {
265 self.as_slice()
266 }
267}
268
269#[cfg(all(test, feature = "alloc"))]
270mod from_iter_tests {
271 use super::Vec;
272
273 #[test]
274 fn from_iter_collects_up_to_n() {
275 let v: Vec<u8, 4> = [1, 2, 3, 4].into_iter().collect();
276 assert_eq!(v.as_slice(), [1, 2, 3, 4]);
277 }
278
279 #[test]
280 #[should_panic(expected = "Vec::from_iter overflow")]
281 fn from_iter_panics_when_more_than_n() {
282 let _: Vec<u8, 2> = [1_u8, 2, 3].into_iter().collect();
283 }
284
285 #[test]
286 #[should_panic(expected = "Vec::from_iter overflow")]
287 fn from_iter_panics_despite_lying_upper_hint() {
288 struct BadHint<I>(I);
289 impl<I: Iterator<Item = u8>> Iterator for BadHint<I> {
290 type Item = u8;
291 fn next(&mut self) -> Option<Self::Item> {
292 self.0.next()
293 }
294 fn size_hint(&self) -> (usize, Option<usize>) {
295 (0, Some(1))
296 }
297 }
298 let _: Vec<u8, 2> = BadHint([1_u8, 2, 3].into_iter()).collect();
299 }
300}