ora-timer 0.2.0

Part of the Ora scheduler framework.
Documentation
#[derive(Debug)]
pub struct Entry<T, R> {
    pub entry: T,
    pub rest: R,
}

const NUM_SLOTS: usize = 256;

type Entries<T, R> = alloc::vec::Vec<Entry<T, R>>;

#[must_use]
#[derive(Debug)]
pub struct ByteWheel<T, R> {
    slots: [Option<Entries<T, R>>; NUM_SLOTS],
    count: usize,
    current: u8,
}

impl<T, R> ByteWheel<T, R> {
    const INIT_VALUE: Option<Entries<T, R>> = None;

    pub fn new() -> Self {
        ByteWheel {
            slots: [Self::INIT_VALUE; NUM_SLOTS],
            count: 0,
            current: 0,
        }
    }

    pub fn insert(&mut self, pos: u8, e: T, r: R) {
        let index = pos as usize;
        self.slots[index]
            .get_or_insert_with(Default::default)
            .push(Entry { entry: e, rest: r });
        self.count += 1;
    }

    #[must_use]
    pub const fn len(&self) -> usize {
        self.count
    }

    #[must_use]
    pub const fn is_empty(&self) -> bool {
        self.count == 0
    }

    #[must_use]
    pub const fn current(&self) -> u8 {
        self.current
    }

    pub fn set_current(&mut self, current: u8) {
        self.current = current;
    }

    pub fn tick(&mut self) -> (impl Iterator<Item = Entry<T, R>>, u8) {
        self.current = self.current.wrapping_add(1u8);
        let index = self.current as usize;
        let cur = self.slots[index].take();
        if let Some(l) = &cur {
            self.count = self.count.saturating_sub(l.len());
        }
        (cur.unwrap_or_default().into_iter(), self.current)
    }
}

impl<EntryType, RestType> Default for ByteWheel<EntryType, RestType> {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn smoke() {
        let mut w: ByteWheel<usize, [u8; 0]> = ByteWheel::new();
        w.insert(2, 0, []);
        assert_eq!(w.current(), 0);
        let (slot, prev_current) = w.tick();
        assert_eq!(slot.count(), 0);
        assert_eq!(prev_current, 1);

        let (mut slot, prev_current) = w.tick();
        assert_eq!(slot.next().unwrap().entry, 0);
        assert_eq!(prev_current, 2);
    }
}