fixed_index_vec/lib.rs
1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3use std::collections::{BTreeMap, HashMap};
4use std::fmt::Display;
5
6/// A fixed-size indexed vector that maps indices to values.
7///
8/// It provides a fixed-size vector-like data structure that can store values based on its
9/// associated index.
10/// Each value is associated with a unique index in the map.
11/// The values can be
12/// accessed, inserted, and removed using the index as the identifier.
13///
14/// # Examples
15///
16/// ```
17/// use fixed_index_vec::FixedIndexVec;
18///
19/// let mut vec = FixedIndexVec::new();
20///
21/// vec.insert("value1".to_string());
22/// vec.insert("value2".to_string());
23///
24/// assert_eq!(vec.get(0), Some(&"value1".to_string()));
25/// assert_eq!(vec.get(1), Some(&"value2".to_string()));
26///
27/// vec.remove(1);
28///
29/// assert_eq!(vec.get(1), None);
30/// ```
31///
32/// # Notes
33///
34/// - The `FixedIndexVec` is backed by a `BTreeMap`, so it is not as fast as a `Vec`.
35/// - Index notations are supported (eg. `vec[0]`), however, accessing an index that does not
36/// exist will panic.
37#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub struct FixedIndexVec<T> {
40 map: BTreeMap<usize, T>,
41 next_index: usize,
42}
43
44impl<T: Display> Display for FixedIndexVec<T> {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 let mut s = String::new();
47 for (i, v) in self.iter() {
48 s.push_str(&format!("{}: {}\n", i, v));
49 }
50 write!(f, "{}", s)
51 }
52}
53
54impl<T> FixedIndexVec<T> {
55 /// Creates an empty `FixedIndexVec`.
56 ///
57 /// The internal storage will not allocate until elements are pushed onto it.
58 ///
59 /// # Examples
60 ///
61 /// ```
62 /// use fixed_index_vec::FixedIndexVec;
63 /// let mut vec: FixedIndexVec<i32> = FixedIndexVec::new();
64 /// ```
65 pub fn new() -> FixedIndexVec<T> {
66 FixedIndexVec {
67 map: BTreeMap::new(),
68 next_index: 0,
69 }
70 }
71
72 /// Inserts an element at the end of the `FixedIndexVec`.
73 ///
74 /// # Panics
75 ///
76 /// Panics if the `FixedIndexVec` is at capacity.
77 ///
78 /// # Examples
79 ///
80 /// ```
81 /// use fixed_index_vec::FixedIndexVec;
82 ///
83 /// let mut vec = FixedIndexVec::new();
84 /// vec.push(1);
85 /// vec.push(2);
86 /// assert_eq!(vec[0], 1);
87 /// assert_eq!(vec[1], 2);
88 /// ```
89 pub fn push(&mut self, value: T) {
90 self.map.insert(self.next_index, value);
91 self.next_index += 1;
92 }
93
94 /// Alias for `push`.
95 /// Inserts an element at the end of the `FixedIndexVec`.
96 ///
97 /// # Panics
98 ///
99 /// Panics if the `FixedIndexVec` is at capacity.
100 ///
101 /// # Examples
102 ///
103 /// ```
104 /// use fixed_index_vec::FixedIndexVec;
105 ///
106 /// let mut vec = FixedIndexVec::new();
107 /// vec.insert(1);
108 /// vec.insert(2);
109 /// assert_eq!(vec[0], 1);
110 /// assert_eq!(vec[1], 2);
111 /// ```
112 pub fn insert(&mut self, value: T) {
113 self.push(value);
114 }
115
116 /// Removes the element at the given index, if it exists, returning it or `None` if it does not exist.
117 ///
118 /// # Examples
119 ///
120 /// ```
121 /// use fixed_index_vec::FixedIndexVec;
122 ///
123 /// let mut vec = FixedIndexVec::new();
124 /// vec.push(1);
125 /// vec.push(2);
126 /// assert_eq!(vec.remove(0), Some(1));
127 /// assert_eq!(vec.remove(0), None);
128 /// ```
129 ///
130 /// # Notes
131 ///
132 /// Unlike `Vec::remove`, this does not shift elements after the removed element.
133 /// If index >= length, this returns `None`, the same as if the element did not exist.
134 pub fn remove(&mut self, index: usize) -> Option<T> {
135 self.map.remove(&index)
136 }
137
138 /// Returns a reference to the element at the given index,
139 /// if it exists, or `None` if it does not exist.
140 ///
141 /// # Examples
142 ///
143 /// ```
144 /// use fixed_index_vec::FixedIndexVec;
145 ///
146 /// let mut vec = FixedIndexVec::new();
147 /// vec.push(1);
148 /// vec.push(2);
149 /// assert_eq!(vec.get(0), Some(&1));
150 /// assert_eq!(vec.get(2), None);
151 /// ```
152 pub fn get(&self, index: usize) -> Option<&T> {
153 self.map.get(&index)
154 }
155
156 /// An iterator visiting all elements in ascending order of their indices.
157 /// The index is returned along with the value.
158 /// The iterator skips indices that do not have a corresponding value.
159 ///
160 /// # Examples
161 ///
162 /// ```
163 /// use fixed_index_vec::FixedIndexVec;
164 ///
165 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
166 /// vec.remove(1);
167 /// let mut iter = vec.iter();
168 /// assert_eq!(iter.next(), Some((0, &1)));
169 /// assert_eq!(iter.next(), Some((2, &3)));
170 /// assert_eq!(iter.next(), None);
171 /// ```
172 pub fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
173 self.map.iter().map(|(i, v)| (*i, v))
174 }
175
176 /// Returns the number of elements in the `FixedIndexVec`.
177 /// This is not the same as the value of the largest index, unless no elements have been removed.
178 ///
179 /// # Examples
180 ///
181 /// ```
182 /// use fixed_index_vec::FixedIndexVec;
183 ///
184 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
185 /// vec.remove(1);
186 /// assert_eq!(vec.len(), 2);
187 /// ```
188 pub fn len(&self) -> usize {
189 self.map.len()
190 }
191
192 /// Returns `true` if the `FixedIndexVec` contains no elements.
193 ///
194 /// # Examples
195 ///
196 /// ```
197 /// use fixed_index_vec::FixedIndexVec;
198 ///
199 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
200 /// vec.remove(1);
201 /// assert_eq!(vec.is_empty(), false);
202 /// ```
203 /// ```
204 /// use fixed_index_vec::FixedIndexVec;
205 /// let vec: FixedIndexVec<i32> = FixedIndexVec::new();
206 /// assert_eq!(vec.is_empty(), true);
207 /// ```
208 pub fn is_empty(&self) -> bool {
209 self.map.is_empty()
210 }
211
212 /// Clears the `FixedIndexVec`, removing all values.
213 /// Keeps the allocated memory for reuse.
214 /// This is equivalent to calling `remove` on every index.
215 /// The next index will *not* be reset to 0.
216 ///
217 /// # Examples
218 /// ```
219 /// use fixed_index_vec::FixedIndexVec;
220 ///
221 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
222 /// vec.clear();
223 /// assert_eq!(vec.len(), 0);
224 /// assert_eq!(vec.next_index(), 3);
225 /// ```
226 pub fn clear(&mut self) {
227 self.map.clear();
228 }
229
230 /// Clears the `FixedIndexVec`, removing all values and resetting the next index to 0.
231 /// Keeps the allocated memory for reuse.
232 ///
233 /// # Examples
234 ///
235 /// ```
236 /// use fixed_index_vec::FixedIndexVec;
237 ///
238 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
239 /// vec.reset();
240 /// assert_eq!(vec.len(), 0);
241 /// assert_eq!(vec.next_index(), 0);
242 /// ```
243 pub fn reset(&mut self) {
244 self.map.clear();
245 self.next_index = 0;
246 }
247
248 /// Returns the next index that will be used when inserting an element.
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use fixed_index_vec::FixedIndexVec;
254 ///
255 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
256 /// vec.remove(1);
257 /// assert_eq!(vec.next_index(), 3);
258 /// ```
259 pub fn next_index(&self) -> usize {
260 self.next_index
261 }
262
263 /// Returns the index and a reference to the element at the smallest populated index, or `None`
264 /// if the `FixedIndexVec` is empty.
265 ///
266 /// # Examples
267 ///
268 /// ```
269 /// use fixed_index_vec::FixedIndexVec;
270 ///
271 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
272 /// vec.remove(0);
273 /// assert_eq!(vec.first(), Some((1, &2)));
274 /// ```
275 /// ```
276 /// use fixed_index_vec::FixedIndexVec;
277 ///
278 /// let vec: FixedIndexVec<i32> = FixedIndexVec::new();
279 /// assert_eq!(vec.first(), None);
280 pub fn first(&self) -> Option<(usize, &T)> {
281 self.iter().next()
282 }
283
284 /// Returns the index and a reference to the element at the largest populated index, or `None`
285 /// if the `FixedIndexVec` is empty.
286 ///
287 /// # Examples
288 ///
289 /// ```
290 /// use fixed_index_vec::FixedIndexVec;
291 ///
292 /// let mut vec: FixedIndexVec<i32> = vec![1, 2, 3].into();
293 /// vec.remove(2);
294 /// assert_eq!(vec.last(), Some((1, &2)));
295 /// ```
296 /// ```
297 /// use fixed_index_vec::FixedIndexVec;
298 ///
299 /// let vec: FixedIndexVec<i32> = FixedIndexVec::new();
300 /// assert_eq!(vec.last(), None);
301 /// ```
302 pub fn last(&self) -> Option<(usize, &T)> {
303 self.iter().last()
304 }
305}
306
307impl<T> std::ops::Index<usize> for FixedIndexVec<T> {
308 type Output = T;
309
310 fn index(&self, index: usize) -> &T {
311 self.get(index).unwrap()
312 }
313}
314
315impl<T> FromIterator<T> for FixedIndexVec<T> {
316 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> FixedIndexVec<T> {
317 let mut map = BTreeMap::new();
318 for (i, v) in iter.into_iter().enumerate() {
319 map.insert(i, v);
320 }
321 FixedIndexVec {
322 next_index: map.len(),
323 map,
324 }
325 }
326}
327
328impl<T> Extend<T> for FixedIndexVec<T> {
329 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
330 for v in iter.into_iter() {
331 self.push(v);
332 }
333 }
334}
335
336impl<T> From<Vec<T>> for FixedIndexVec<T> {
337 fn from(vec: Vec<T>) -> FixedIndexVec<T> {
338 vec.into_iter().collect()
339 }
340}
341
342impl<T, A> From<HashMap<A, T>> for FixedIndexVec<T> {
343 fn from(map: HashMap<A, T>) -> FixedIndexVec<T> {
344 map.into_values().collect()
345 }
346}
347
348impl<T, A> From<BTreeMap<A, T>> for FixedIndexVec<T> {
349 fn from(map: BTreeMap<A, T>) -> FixedIndexVec<T> {
350 map.into_values().collect()
351 }
352}
353
354#[cfg(test)]
355mod tests {
356 use super::FixedIndexVec;
357
358 #[test]
359 fn test_send() {
360 fn assert_send<T: Send>() {}
361 assert_send::<FixedIndexVec<i32>>();
362 assert_send::<FixedIndexVec<f32>>();
363 assert_send::<FixedIndexVec<String>>();
364 }
365 #[test]
366 fn test_sync() {
367 fn assert_sync<T: Sync>() {}
368 assert_sync::<FixedIndexVec<i32>>();
369 assert_sync::<FixedIndexVec<f32>>();
370 assert_sync::<FixedIndexVec<String>>();
371 }
372}