Skip to main content

nanvm_lib/common/
index_iter.rs

1use core::iter::FusedIterator;
2
3use crate::common::{default::default, sized_index::SizedIndex, uint::Uint};
4
5pub struct IndexIter<I, T> {
6    container: T,
7    i: I,
8}
9
10impl<I: Uint, T: SizedIndex<I>> IndexIter<I, T> {
11    pub fn new(container: T) -> Self {
12        Self {
13            container,
14            i: default(),
15        }
16    }
17}
18
19impl<I: Uint, T: SizedIndex<I, Output: Clone>> Iterator for IndexIter<I, T> {
20    type Item = T::Output;
21    fn next(&mut self) -> Option<Self::Item> {
22        let i = self.i;
23        if i == self.container.length() {
24            return None;
25        }
26        self.i += 1.into();
27        Some(self.container[i].clone())
28    }
29    /// Exact: a [`SizedIndex`]'s length is fixed.
30    fn size_hint(&self) -> (usize, Option<usize>) {
31        let left = (self.container.length() - self.i).to_usize();
32        (left, Some(left))
33    }
34}
35
36impl<I: Uint, T: SizedIndex<I, Output: Clone>> ExactSizeIterator for IndexIter<I, T> {}
37
38impl<I: Uint, T: SizedIndex<I, Output: Clone>> FusedIterator for IndexIter<I, T> {}
39
40#[cfg(test)]
41mod tests {
42    use crate::{naive::Naive, vm::String};
43
44    #[test]
45    fn exact_and_fused() {
46        let s: String<Naive> = "ab".into();
47        let mut i = s.into_iter();
48        assert_eq!(i.len(), 2);
49        assert_eq!(i.next(), Some(0x61));
50        assert_eq!(i.size_hint(), (1, Some(1)));
51        assert_eq!(i.next(), Some(0x62));
52        assert_eq!(i.len(), 0);
53        assert_eq!(i.next(), None);
54        assert_eq!(i.next(), None);
55    }
56}