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 entries of the `TaggedVec`.
48    pub fn iter(&self) -> impl Iterator<Item = (Index, &Value)>
49    where
50        Index: From<usize>,
51    {
52        self.vec
53            .iter()
54            .enumerate()
55            .map(|(index, value)| (index.into(), value))
56    }
57
58    /// Returns an iterator over mutable references to the entries of the `TaggedVec`.
59    pub fn iter_mut(&mut self) -> impl Iterator<Item = (Index, &mut Value)>
60    where
61        Index: From<usize>,
62    {
63        self.vec
64            .iter_mut()
65            .enumerate()
66            .map(|(index, value)| (index.into(), value))
67    }
68
69    /// Returns an iterator over references to the values of the `TaggedVec`.
70    pub fn iter_values(&self) -> std::slice::Iter<'_, Value> {
71        self.vec.iter()
72    }
73
74    /// Returns an iterator over mutable references to the values of the `TaggedVec`.
75    pub fn iter_values_mut(&mut self) -> std::slice::IterMut<'_, Value> {
76        self.vec.iter_mut()
77    }
78
79    /// Returns an iterator over the indices of the `TaggedVec`.
80    pub fn iter_indices(&self) -> impl Iterator<Item = Index>
81    where
82        Index: From<usize>,
83    {
84        (0..self.vec.len()).map(Into::into)
85    }
86}