typed_slab/
lib.rs

1//! A crate with a typed wrapper for [`Slab`].
2
3#![warn(missing_docs)]
4
5pub use slab::Slab;
6
7use derive_more::{Deref, DerefMut};
8use std::marker::PhantomData;
9
10/// Pre-allocated storage for a uniform data type with indeces
11/// converted from and into `usize`.
12#[derive(Debug, Deref, DerefMut)]
13pub struct TypedSlab<K, V> {
14    #[deref]
15    #[deref_mut]
16    slab: Slab<V>,
17    _key: PhantomData<K>,
18}
19
20impl<K, V> Default for TypedSlab<K, V> {
21    fn default() -> Self {
22        Self {
23            slab: Slab::default(),
24            _key: PhantomData,
25        }
26    }
27}
28
29impl<K, V> TypedSlab<K, V>
30where
31    K: From<usize> + Into<usize>,
32{
33    /// Construct a new, empty `TypedSlab`.
34    pub fn new() -> Self {
35        Self {
36            slab: Slab::new(),
37            _key: PhantomData,
38        }
39    }
40
41    /// Insert a value in the slab, returning key assigned to the value.
42    pub fn insert(&mut self, value: V) -> K {
43        let idx = self.slab.insert(value);
44        K::from(idx)
45    }
46
47    /// Insert a value in the slab, returning key assigned and a reference
48    /// to the stored value.
49    pub fn insert_entry(&mut self, value: V) -> (K, &mut V) {
50        let entry = self.slab.vacant_entry();
51        let idx = entry.key();
52        let value_mut = entry.insert(value);
53        (K::from(idx), value_mut)
54    }
55
56    /// Remove and return the value associated with the given key.
57    /// The key is then released and may be associated with future stored values.
58    ///
59    /// # Panics
60    ///
61    /// Panics if key is not associated with a value.
62    ///
63    pub fn remove(&mut self, key: K) -> Option<V> {
64        let idx = key.into();
65        if self.slab.contains(idx) {
66            let value = self.slab.remove(idx);
67            Some(value)
68        } else {
69            None
70        }
71    }
72
73    /// Return a reference to the value associated with the given key.
74    /// If the given key is not associated with a value, then `None` is returned.
75    pub fn get(&self, key: K) -> Option<&V> {
76        let idx = key.into();
77        self.slab.get(idx)
78    }
79
80    /// Return a mutable reference to the value associated with the given key.
81    /// If the given key is not associated with a value, then `None` is returned.
82    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
83        let idx = key.into();
84        self.slab.get_mut(idx)
85    }
86
87    /// Return true if there are no values stored in the slab.
88    pub fn is_empty(&self) -> bool {
89        self.slab.is_empty()
90    }
91
92    /// Return an iterator over the slab.
93    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (K, &V)> {
94        self.slab.iter().map(|(idx, v)| (idx.into(), v))
95    }
96
97    /// Return an iterator that allows modifying each value.
98    pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (K, &mut V)> {
99        self.slab.iter_mut().map(|(idx, v)| (idx.into(), v))
100    }
101
102    /// Return an iterator with references to values.
103    pub fn values(&self) -> impl DoubleEndedIterator<Item = &V> {
104        self.slab.iter().map(|(_, v)| v)
105    }
106
107    /// Return a draining iterator that removes all elements from the slab
108    /// and yields the removed items.
109    pub fn drain(&mut self) -> impl DoubleEndedIterator<Item = V> + '_ {
110        self.slab.drain()
111    }
112
113    /// Return a number of stored values.
114    pub fn len(&self) -> usize {
115        self.slab.len()
116    }
117}
118
119#[cfg(test)]
120mod test {
121    use super::*;
122
123    #[test]
124    fn test_rev() {
125        let slab: TypedSlab<usize, ()> = TypedSlab::new();
126        let _iter = slab.iter().rev();
127    }
128}