reactive-signals 0.1.0-alpha.4

reactive-signals is a dx-first scope-based fine-grained reactive system.
Documentation
pub(crate) trait IdVec {
    type Output;
    fn get(&self, idx: usize) -> Self::Output;
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool;
}

pub(crate) struct IdVecIter<V: IdVec> {
    vec: V,
    pos: usize,
    len: usize,
}

impl<V: IdVec> IdVecIter<V> {
    pub(crate) fn new(vec: V) -> Self {
        let len = vec.len();
        Self {
            vec,
            pos: usize::MAX,
            len,
        }
    }

    pub(crate) fn remaining(&self) -> usize {
        if self.pos == usize::MAX {
            self.len
        } else {
            self.len - self.pos - 1
        }
    }

    pub(crate) fn has_more(&self) -> bool {
        self.len - 1 > self.pos
    }
}

impl<V: IdVec> Iterator for IdVecIter<V> {
    type Item = V::Output;

    fn next(&mut self) -> Option<Self::Item> {
        if self.pos == usize::MAX {
            if self.vec.is_empty() {
                None
            } else {
                self.pos = 0;
                Some(self.vec.get(0))
            }
        } else if self.pos + 1 >= self.vec.len() {
            None
        } else {
            self.pos += 1;
            let id = self.vec.get(self.pos);
            Some(id)
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let remaining = self.remaining();
        (remaining, Some(remaining))
    }
}

impl<V: IdVec> ExactSizeIterator for IdVecIter<V> {
    fn len(&self) -> usize {
        self.vec.len()
    }
}

#[cfg(test)]
impl IdVec for Vec<usize> {
    type Output = usize;
    fn get(&self, idx: usize) -> Self::Output {
        self[idx]
    }

    fn len(&self) -> usize {
        self.len()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }
}

#[test]
fn test_id_vec() {
    assert_eq!(IdVecIter::new(vec![]).next(), None);

    let mut iter = IdVecIter::new(vec![0, 1, 2]);
    assert_eq!(iter.remaining(), 3);

    let val = iter.next();
    assert_eq!(val, Some(0));
    assert_eq!(iter.remaining(), 2);
    assert_eq!(iter.has_more(), true);

    let val = iter.next();
    assert_eq!(val, Some(1));
    assert_eq!(iter.has_more(), true);
    assert_eq!(iter.remaining(), 1);

    let val = iter.next();
    assert_eq!(val, Some(2));
    assert_eq!(iter.has_more(), false);
    assert_eq!(iter.remaining(), 0);

    let val = iter.next();
    assert_eq!(val, None);
    assert_eq!(iter.has_more(), false);
    assert_eq!(iter.remaining(), 0);
}