rune/runtime/slice/
iter.rs

1use crate as rune;
2use crate::runtime::{Ref, Value};
3use crate::Any;
4
5/// An efficient reference counter iterator over a vector.
6#[derive(Any)]
7#[rune(item = ::std::slice)]
8pub struct Iter {
9    vec: Ref<[Value]>,
10    front: usize,
11    back: usize,
12}
13
14impl Iter {
15    pub(crate) fn new(vec: Ref<[Value]>) -> Self {
16        let back = vec.len();
17
18        Self {
19            vec,
20            front: 0,
21            back,
22        }
23    }
24
25    #[rune::function(instance, keep, protocol = NEXT)]
26    #[inline]
27    fn next(&mut self) -> Option<Value> {
28        if self.front == self.back {
29            return None;
30        }
31
32        let value = self.vec.get(self.front)?;
33        self.front = self.front.wrapping_add(1);
34        Some(value.clone())
35    }
36
37    #[rune::function(instance, keep, protocol = NTH)]
38    #[inline]
39    fn nth(&mut self, n: usize) -> Option<Value> {
40        let n = self.front.wrapping_add(n);
41
42        if n >= self.back || n < self.front {
43            return None;
44        }
45
46        let value = self.vec.get(n)?;
47        self.front = n.wrapping_add(1);
48        Some(value.clone())
49    }
50
51    #[rune::function(instance, keep, protocol = SIZE_HINT)]
52    #[inline]
53    fn size_hint(&self) -> (usize, Option<usize>) {
54        let len = self.back.wrapping_sub(self.front);
55        (len, Some(len))
56    }
57
58    #[rune::function(instance, keep, protocol = LEN)]
59    #[inline]
60    fn len(&self) -> usize {
61        self.back.wrapping_sub(self.front)
62    }
63
64    #[rune::function(instance, keep, protocol = NEXT_BACK)]
65    #[inline]
66    fn next_back(&mut self) -> Option<Value> {
67        if self.front == self.back {
68            return None;
69        }
70
71        self.back = self.back.wrapping_sub(1);
72        let value = self.vec.get(self.back)?;
73        Some(value.clone())
74    }
75}
76
77impl Iterator for Iter {
78    type Item = Value;
79
80    #[inline]
81    fn next(&mut self) -> Option<Self::Item> {
82        Iter::next(self)
83    }
84
85    #[inline]
86    fn nth(&mut self, n: usize) -> Option<Self::Item> {
87        Iter::nth(self, n)
88    }
89
90    #[inline]
91    fn size_hint(&self) -> (usize, Option<usize>) {
92        Iter::size_hint(self)
93    }
94}
95
96impl DoubleEndedIterator for Iter {
97    #[inline]
98    fn next_back(&mut self) -> Option<Self::Item> {
99        Iter::next_back(self)
100    }
101}