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> Pool<T, N> {
10    const CAPACITY: usize = N;
11    const INIT_ITEM: AchOption<T> = AchOption::new();
12    pub const fn new() -> Self {
13        Pool {
14            buf: [Self::INIT_ITEM; N],
15        }
16    }
17    pub const fn capacity(&self) -> usize {
18        Self::CAPACITY
19    }
20    pub fn is_empty(&self) -> bool {
21        self.buf.iter().all(|x| x.is_none())
22    }
23    pub fn is_full(&self) -> bool {
24        self.buf.iter().all(|x| x.is_some())
25    }
26    pub fn clear(&mut self) {
27        self.buf = [Self::INIT_ITEM; N];
28    }
29    /// pop a value from random position
30    pub fn pop(&self) -> Option<T> {
31        for index in 0..self.capacity() {
32            if let Ok(Some(x)) = self.buf[index].try_take() {
33                return Some(x);
34            }
35        }
36        None
37    }
38    /// push a value to random position, return index
39    pub fn push(&self, mut value: T) -> Result<usize, T> {
40        for index in 0..self.capacity() {
41            if let Err(v) = self.buf[index].try_set(value) {
42                value = v.input;
43            } else {
44                return Ok(index);
45            }
46        }
47        Err(value)
48    }
49}
50impl<T, const N: usize> Index<usize> for Pool<T, N> {
51    type Output = AchOption<T>;
52    fn index(&self, index: usize) -> &Self::Output {
53        &self.buf[index]
54    }
55}