wai_bindgen_wasmer/
slab.rs

1use std::fmt;
2use std::mem;
3
4pub struct Slab<T> {
5    storage: Vec<Entry<T>>,
6    next: usize,
7}
8
9enum Entry<T> {
10    Full(T),
11    Empty { next: usize },
12}
13
14impl<T> Slab<T> {
15    pub fn insert(&mut self, item: T) -> u32 {
16        if self.next == self.storage.len() {
17            self.storage.push(Entry::Empty {
18                next: self.next + 1,
19            });
20        }
21        let ret = self.next as u32;
22        let entry = Entry::Full(item);
23        self.next = match mem::replace(&mut self.storage[self.next], entry) {
24            Entry::Empty { next } => next,
25            _ => unreachable!(),
26        };
27        ret
28    }
29
30    pub fn get(&self, idx: u32) -> Option<&T> {
31        match self.storage.get(idx as usize)? {
32            Entry::Full(b) => Some(b),
33            Entry::Empty { .. } => None,
34        }
35    }
36
37    pub fn get_mut(&mut self, idx: u32) -> Option<&mut T> {
38        match self.storage.get_mut(idx as usize)? {
39            Entry::Full(b) => Some(b),
40            Entry::Empty { .. } => None,
41        }
42    }
43
44    pub fn remove(&mut self, idx: u32) -> Option<T> {
45        let slot = self.storage.get_mut(idx as usize)?;
46        match mem::replace(slot, Entry::Empty { next: self.next }) {
47            Entry::Full(b) => {
48                self.next = idx as usize;
49                Some(b)
50            }
51            Entry::Empty { next } => {
52                *slot = Entry::Empty { next };
53                None
54            }
55        }
56    }
57}
58
59impl<T> Default for Slab<T> {
60    fn default() -> Slab<T> {
61        Slab {
62            storage: Vec::new(),
63            next: 0,
64        }
65    }
66}
67
68impl<T: fmt::Debug> fmt::Debug for Slab<T> {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        f.debug_struct("Slab").finish()
71    }
72}