stuart_core/process/
iter.rs

1//! Provides the [`TokenIter`] iterator over tokens, which is able to be rewound to a [`TokenIterWaypoint`].
2
3use crate::parse::LocatableToken;
4
5/// Represents an iterator over tokens.
6pub struct TokenIter<'a> {
7    /// The tokens to iterate over.
8    tokens: &'a [LocatableToken],
9    /// The current index in the tokens.
10    index: usize,
11}
12
13/// Represents a waypoint in the [`TokenIter`] iterator.
14#[derive(Clone, Copy)]
15pub struct TokenIterWaypoint(usize);
16
17impl<'a> TokenIter<'a> {
18    /// Creates a new iterator over the given tokens.
19    pub fn new(tokens: &'a [LocatableToken]) -> Self {
20        Self { tokens, index: 0 }
21    }
22
23    /// Creates a "waypoint" at the current position.
24    pub fn waypoint(&self) -> TokenIterWaypoint {
25        TokenIterWaypoint(self.index)
26    }
27
28    /// Rewinds the iterator to the given waypoint.
29    pub fn rewind_to(&mut self, waypoint: TokenIterWaypoint) {
30        self.index = waypoint.0;
31    }
32
33    /// Returns the token that is currently being processed.
34    ///
35    /// **Note:** this is the last token that was returned, not the next token to be returned.
36    pub fn current(&self) -> Option<&LocatableToken> {
37        if self.index > 0 {
38            Some(&self.tokens[self.index - 1])
39        } else {
40            None
41        }
42    }
43}
44
45impl<'a> Iterator for TokenIter<'a> {
46    type Item = &'a LocatableToken;
47
48    fn next(&mut self) -> Option<Self::Item> {
49        if self.index < self.tokens.len() {
50            let token = &self.tokens[self.index];
51            self.index += 1;
52            Some(token)
53        } else {
54            None
55        }
56    }
57}