Skip to main content

ach_pool/
lib.rs

1#![no_std]
2
3use ach_option::AchOption;
4use core::ops::Index;
5
6pub struct Pool<T, const N: usize> {
7    buf: [AchOption<T>; N],
8}
9impl<T, const N: usize> Default for Pool<T, N> {
10    fn default() -> Self {
11        Self::new()
12    }
13}
14impl<T, const N: usize> Pool<T, N> {
15    const CAPACITY: usize = N;
16    #[allow(clippy::declare_interior_mutable_const)]
17    const INIT_ITEM: AchOption<T> = AchOption::new();
18    pub const fn new() -> Self {
19        Pool {
20            buf: [Self::INIT_ITEM; N],
21        }
22    }
23    pub const fn capacity(&self) -> usize {
24        Self::CAPACITY
25    }
26    pub fn is_empty(&self) -> bool {
27        self.buf.iter().all(|x| x.is_none())
28    }
29    pub fn is_full(&self) -> bool {
30        self.buf.iter().all(|x| x.is_some())
31    }
32    pub fn clear(&mut self) {
33        self.buf = [Self::INIT_ITEM; N];
34    }
35    /// pop a value from random position
36    pub fn pop(&self) -> Option<T> {
37        for index in 0..self.capacity() {
38            if let Ok(Some(x)) = self.buf[index].try_take() {
39                return Some(x);
40            }
41        }
42        None
43    }
44    /// push a value to random position, return index
45    pub fn push(&self, mut value: T) -> Result<usize, T> {
46        for index in 0..self.capacity() {
47            if let Err(v) = self.buf[index].try_set(value) {
48                value = v.input;
49            } else {
50                return Ok(index);
51            }
52        }
53        Err(value)
54    }
55}
56impl<T, const N: usize> Index<usize> for Pool<T, N> {
57    type Output = AchOption<T>;
58    fn index(&self, index: usize) -> &Self::Output {
59        &self.buf[index]
60    }
61}