tagged_vec/lib.rs
1//! An alternative to the standard libraries' [`Vec`] which is indexed with a custom type instead of [`usize`].
2//!
3//! This is useful to catch errors like using the wrong variable to index the vector.
4
5#![warn(missing_docs)]
6
7use std::marker::PhantomData;
8
9mod trait_impls;
10
11/// A [`Vec`] wrapper that allows indexing only via the given `Index` type.
12///
13/// For actual operation, `Index` must implement [`From<usize>`] and [`Into<usize>`].
14pub struct TaggedVec<Index, Value> {
15 index_type: PhantomData<Index>,
16 vec: Vec<Value>,
17}
18
19impl<Index, Value> TaggedVec<Index, Value> {
20 /// Creates a new empty `TaggedVec`.
21 pub fn new() -> Self {
22 Self::default()
23 }
24
25 /// Inserts the given value at the back of the `Vec`, returning its index.
26 pub fn push(&mut self, value: Value) -> Index
27 where
28 Index: From<usize>,
29 {
30 let index = self.vec.len().into();
31 self.vec.push(value);
32 index
33 }
34
35 /// Removes the value at the back of the `Vec` and returns it with its index.
36 pub fn pop(&mut self) -> Option<(Index, Value)>
37 where
38 Index: From<usize>,
39 {
40 if let Some(value) = self.vec.pop() {
41 Some((self.vec.len().into(), value))
42 } else {
43 None
44 }
45 }
46}