pub trait Pool<V> {
type Error: core::error::Error;
type Iter<'a>: Iterator<Item = (usize, &'a V)>
where
Self: 'a,
V: 'a;
type IterMut<'a>: Iterator<Item = (usize, &'a mut V)>
where
Self: 'a,
V: 'a;
fn new() -> Self;
fn with_capacity(capacity: usize) -> Result<Self, Self::Error>
where
Self: Sized;
fn vacant_key(&self) -> Result<usize, Self::Error>;
fn is_empty(&self) -> bool;
fn len(&self) -> usize;
fn get(&self, key: usize) -> Option<&V>;
fn get_mut(&mut self, key: usize) -> Option<&mut V>;
fn insert(&mut self, value: V) -> Result<usize, Self::Error>;
fn try_remove(&mut self, key: usize) -> Option<V>;
fn iter(&self) -> Self::Iter<'_>;
fn iter_mut(&mut self) -> Self::IterMut<'_>;
}
#[cfg(feature = "slab")]
#[cfg_attr(docsrs, doc(cfg(feature = "slab")))]
impl<T> Pool<T> for slab::Slab<T> {
type Error = core::convert::Infallible;
type Iter<'a>
= slab::Iter<'a, T>
where
Self: 'a;
type IterMut<'a>
= slab::IterMut<'a, T>
where
Self: 'a;
#[inline]
fn new() -> Self {
slab::Slab::new()
}
#[inline]
fn with_capacity(capacity: usize) -> Result<Self, Self::Error>
where
Self: Sized,
{
Ok(slab::Slab::with_capacity(capacity))
}
#[inline]
fn vacant_key(&self) -> Result<usize, Self::Error> {
Ok(slab::Slab::vacant_key(self))
}
#[inline]
fn is_empty(&self) -> bool {
slab::Slab::is_empty(self)
}
#[inline]
fn len(&self) -> usize {
slab::Slab::len(self)
}
#[inline]
fn get(&self, key: usize) -> Option<&T> {
slab::Slab::get(self, key)
}
#[inline]
fn get_mut(&mut self, key: usize) -> Option<&mut T> {
slab::Slab::get_mut(self, key)
}
#[inline]
fn insert(&mut self, value: T) -> Result<usize, Self::Error> {
Ok(slab::Slab::insert(self, value))
}
#[inline]
fn try_remove(&mut self, key: usize) -> Option<T> {
slab::Slab::try_remove(self, key)
}
#[inline]
fn iter(&self) -> Self::Iter<'_> {
slab::Slab::iter(self)
}
#[inline]
fn iter_mut(&mut self) -> Self::IterMut<'_> {
slab::Slab::iter_mut(self)
}
}
#[cfg(feature = "heapless")]
#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))]
mod heapless_impl {
use super::Pool;
#[derive(Debug, Clone, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
#[error("heapless Pool capacity exhausted")]
pub struct HeaplessCapacityError;
pub struct HeaplessIter<'a, V> {
inner: core::iter::Enumerate<core::slice::Iter<'a, Option<V>>>,
}
impl<'a, V> Iterator for HeaplessIter<'a, V> {
type Item = (usize, &'a V);
fn next(&mut self) -> Option<Self::Item> {
for (idx, slot) in self.inner.by_ref() {
if let Some(v) = slot {
return Some((idx, v));
}
}
None
}
}
pub struct HeaplessIterMut<'a, V> {
inner: core::iter::Enumerate<core::slice::IterMut<'a, Option<V>>>,
}
impl<'a, V> Iterator for HeaplessIterMut<'a, V> {
type Item = (usize, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
for (idx, slot) in self.inner.by_ref() {
if let Some(v) = slot {
return Some((idx, v));
}
}
None
}
}
impl<V, const N: usize> Pool<V> for heapless::Vec<Option<V>, N> {
type Error = HeaplessCapacityError;
type Iter<'a>
= HeaplessIter<'a, V>
where
Self: 'a,
V: 'a;
type IterMut<'a>
= HeaplessIterMut<'a, V>
where
Self: 'a,
V: 'a;
#[inline]
fn new() -> Self {
heapless::Vec::new()
}
#[inline]
fn with_capacity(capacity: usize) -> Result<Self, Self::Error> {
if capacity > N {
return Err(HeaplessCapacityError);
}
Ok(heapless::Vec::new())
}
#[inline]
fn vacant_key(&self) -> Result<usize, Self::Error> {
for (idx, slot) in self.as_slice().iter().enumerate() {
if slot.is_none() {
return Ok(idx);
}
}
if heapless::Vec::len(self) < N {
return Ok(heapless::Vec::len(self));
}
Err(HeaplessCapacityError)
}
#[inline]
fn is_empty(&self) -> bool {
self.as_slice().iter().all(Option::is_none)
}
#[inline]
fn len(&self) -> usize {
self.as_slice().iter().filter(|s| s.is_some()).count()
}
#[inline]
fn get(&self, key: usize) -> Option<&V> {
self.as_slice().get(key).and_then(Option::as_ref)
}
#[inline]
fn get_mut(&mut self, key: usize) -> Option<&mut V> {
self.as_mut_slice().get_mut(key).and_then(Option::as_mut)
}
fn insert(&mut self, value: V) -> Result<usize, Self::Error> {
for (idx, slot) in self.as_mut_slice().iter_mut().enumerate() {
if slot.is_none() {
*slot = Some(value);
return Ok(idx);
}
}
let idx = heapless::Vec::len(self);
heapless::Vec::push(self, Some(value)).map_err(|_| HeaplessCapacityError)?;
Ok(idx)
}
#[inline]
fn try_remove(&mut self, key: usize) -> Option<V> {
self.as_mut_slice().get_mut(key).and_then(Option::take)
}
#[inline]
fn iter(&self) -> Self::Iter<'_> {
HeaplessIter {
inner: self.as_slice().iter().enumerate(),
}
}
#[inline]
fn iter_mut(&mut self) -> Self::IterMut<'_> {
HeaplessIterMut {
inner: self.as_mut_slice().iter_mut().enumerate(),
}
}
}
}
#[cfg(feature = "heapless")]
#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))]
pub use heapless_impl::HeaplessCapacityError;
#[cfg(test)]
mod tests;