ach_array/
lib.rs

1#![no_std]
2
3use ach_cell::Cell;
4pub use ach_cell::Ref;
5use core::ops::Index;
6
7pub struct Array<T, const N: usize> {
8    buf: [Cell<T>; N],
9}
10impl<T, const N: usize> Array<T, N> {
11    const CAPACITY: usize = N;
12    const INIT_ITEM: Cell<T> = Cell::new();
13    pub const fn new() -> Self {
14        Array {
15            buf: [Self::INIT_ITEM; N],
16        }
17    }
18    pub const fn capacity(&self) -> usize {
19        Self::CAPACITY
20    }
21    pub fn is_empty(&self) -> bool {
22        self.buf.iter().all(|x| !x.is_initialized())
23    }
24    pub fn is_full(&self) -> bool {
25        self.buf.iter().all(|x| x.is_initialized())
26    }
27    pub fn clear(&mut self) {
28        self.buf = [Self::INIT_ITEM; N];
29    }
30    /// pop a value from random position
31    pub fn pop(&self) -> Option<T> {
32        for index in 0..self.capacity() {
33            if let Ok(Some(x)) = self.buf[index].try_take() {
34                return Some(x);
35            }
36        }
37        None
38    }
39    /// push a value to random position, return index
40    pub fn push(&self, mut value: T) -> Result<usize, T> {
41        for index in 0..self.capacity() {
42            if let Err(v) = self.buf[index].try_set(value) {
43                value = v.input;
44            } else {
45                return Ok(index);
46            }
47        }
48        Err(value)
49    }
50    /// It will ignore values which is transient if strict is `false`
51    /// Notice: `Spin` if strict
52    pub fn iter(&self, strict: bool) -> ArrayIterator<T, N> {
53        ArrayIterator {
54            vec: self,
55            index: 0,
56            strict,
57        }
58    }
59}
60impl<T, const N: usize> Index<usize> for Array<T, N> {
61    type Output = Cell<T>;
62    fn index(&self, index: usize) -> &Self::Output {
63        &self.buf[index]
64    }
65}
66
67pub struct ArrayIterator<'a, T, const N: usize> {
68    vec: &'a Array<T, N>,
69    index: usize,
70    strict: bool,
71}
72impl<'a, T, const N: usize> Iterator for ArrayIterator<'a, T, N> {
73    type Item = Ref<'a, T>;
74    fn next(&mut self) -> Option<Self::Item> {
75        if self.index >= self.vec.capacity() {
76            return None;
77        }
78        let ret = if self.strict {
79            self.vec[self.index].get()
80        } else {
81            self.vec[self.index].try_get()
82        };
83        self.index += 1;
84        if let Ok(ret) = ret {
85            Some(ret)
86        } else {
87            self.next()
88        }
89    }
90}