slabbable_stablevec/
lib.rs1#![warn(
2 clippy::unwrap_used,
3 missing_docs,
4 rust_2018_idioms,
5 unused_lifetimes,
6 unused_qualifications
7)]
8#![allow(clippy::single_match, rustdoc::bare_urls)]
9#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
10#![doc = include_str!("../README.md")]
11
12use slabbable::{ReservedSlot, Slabbable, SlabbableError};
22
23#[derive(Debug)]
24enum ReserveStatus<Item> {
25 Reserved,
26 Taken(Item),
27}
28
29use stable_vec::{core::BitVecCore, StableVecFacade};
30
31#[derive(Debug)]
33pub struct StableVecSlab<Item> {
34 inner: StableVecFacade<ReserveStatus<Item>, BitVecCore<ReserveStatus<Item>>>,
35}
36
37impl<Item> Slabbable<StableVecSlab<Item>, Item> for StableVecSlab<Item>
38where
39 Item: core::fmt::Debug + Clone,
40{
41 type Error = SlabbableError;
42 fn with_fixed_capacity(cap: usize) -> Result<Self, Self::Error> {
44 Ok(Self {
45 inner: StableVecFacade::<ReserveStatus<Item>, BitVecCore<ReserveStatus<Item>>>::with_capacity(cap),
46 })
47 }
48 #[inline]
50 fn reserve_next(&mut self) -> Result<ReservedSlot, Self::Error> {
51 if self.inner.capacity() < self.inner.num_elements() + 1 {
53 return Err(SlabbableError::AtCapacity(self.inner.capacity()));
54 }
55 let ins = self.inner.push(ReserveStatus::Reserved);
56 Ok(ReservedSlot::issue(ins))
57 }
58 #[inline]
59 fn take_reserved_with(
60 &mut self,
61 r_slot: ReservedSlot,
62 with: Item,
63 ) -> Result<usize, Self::Error> {
64 let slot = r_slot.id();
65
66 let v = match self.inner.get_mut(slot) {
67 Some(v) => match v {
68 ReserveStatus::Reserved => v,
69 _ => return Err(SlabbableError::InvalidIndex(slot)),
70 },
71 _ => return Err(SlabbableError::InvalidIndex(slot)),
72 };
73 *v = ReserveStatus::Taken(with);
74 Ok(slot)
75 }
76 #[inline]
78 fn take_next_with(&mut self, with: Item) -> Result<usize, Self::Error> {
79 let reserved_slot = self.reserve_next()?;
80 self.take_reserved_with(reserved_slot, with)
81 }
82 #[inline]
84 fn mark_for_reuse(&mut self, slot: usize) -> Result<Item, Self::Error> {
85 if slot > self.inner.capacity() {
86 return Err(SlabbableError::InvalidIndex(slot));
87 }
88 match self.inner.remove(slot) {
89 Some(ReserveStatus::Taken(i)) => Ok(i),
90 _ => Err(SlabbableError::InvalidIndex(slot)),
91 }
92 }
93 #[inline]
95 fn slot_get_ref(&self, slot: usize) -> Result<Option<&Item>, Self::Error> {
96 if slot > self.inner.capacity() {
97 return Err(SlabbableError::InvalidIndex(slot));
98 }
99 match self.inner.get(slot) {
100 Some(ReserveStatus::Taken(itm_ref)) => Ok(Some(itm_ref)),
101 _ => Err(SlabbableError::InvalidIndex(slot)),
102 }
103 }
104 #[inline]
106 fn slot_get_mut(&mut self, slot: usize) -> Result<Option<&mut Item>, Self::Error> {
107 if slot > self.inner.capacity() {
108 return Err(SlabbableError::InvalidIndex(slot));
109 }
110 match self.inner.get_mut(slot) {
111 Some(ReserveStatus::Taken(itm_ref)) => Ok(Some(itm_ref)),
112 _ => Err(SlabbableError::InvalidIndex(slot)),
113 }
114 }
115 #[inline]
117 fn capacity(&self) -> usize {
118 self.inner.capacity()
119 }
120 #[inline]
122 fn remaining(&self) -> Option<usize> {
123 let rem = self.inner.capacity() - self.inner.num_elements();
124 match rem {
125 0 => None,
126 1_usize.. => Some(rem),
127 }
128 }
129 fn reap(&mut self) -> Option<usize> {
131 None
133 }
134}