wai_bindgen_wasmer/
slab.rs1use 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}