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 `TaggedVec`, 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 `TaggedVec` 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
47    /// Returns an iterator over references to the elements of the `TaggedVec`.
48    pub fn iter(&self) -> std::slice::Iter<'_, Value> {
49        self.vec.iter()
50    }
51
52    /// Returns an iterator over mutable references to the elements of the `TaggedVec`.
53    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, Value> {
54        self.vec.iter_mut()
55    }
56}