cargo_cargofmt/toml/
mod.rs

1mod tokens;
2
3pub use tokens::Encoding;
4pub use tokens::ScalarKind;
5pub use tokens::TokenKind;
6pub use tokens::TomlToken;
7pub use tokens::TomlTokens;
8
9pub struct TokenIndices {
10    i: usize,
11}
12
13impl TokenIndices {
14    pub fn new() -> Self {
15        Self { i: 0 }
16    }
17
18    pub fn from_index(i: usize) -> Self {
19        Self { i }
20    }
21
22    pub fn next_index(&mut self, tokens: &TomlTokens<'_>) -> Option<usize> {
23        if self.i < tokens.len() {
24            let i = self.i;
25            self.i += 1;
26            Some(i)
27        } else {
28            None
29        }
30    }
31
32    pub fn prev_index(&mut self, _tokens: &TomlTokens<'_>) -> Option<usize> {
33        if self.i > 0 {
34            self.i -= 1;
35            Some(self.i)
36        } else {
37            None
38        }
39    }
40
41    pub fn set_next_index(&mut self, i: usize) {
42        self.i = i;
43    }
44
45    pub fn rev(&self) -> impl Iterator<Item = usize> {
46        (0..self.i).rev()
47    }
48}
49
50impl Default for TokenIndices {
51    fn default() -> Self {
52        Self::new()
53    }
54}
55
56#[cfg(test)]
57mod test {
58    use super::*;
59
60    #[test]
61    fn next_index_iterates_forward() {
62        let tokens = TomlTokens::parse("a = 1");
63        let mut indices = TokenIndices::new();
64        assert_eq!(indices.next_index(&tokens), Some(0));
65        assert_eq!(indices.next_index(&tokens), Some(1));
66        assert_eq!(indices.next_index(&tokens), Some(2));
67    }
68
69    #[test]
70    fn next_index_returns_none_at_end() {
71        let tokens = TomlTokens::parse("a = 1");
72        let mut indices = TokenIndices::new();
73        // Exhaust all indices
74        while indices.next_index(&tokens).is_some() {}
75        // Should return None when exhausted
76        assert_eq!(indices.next_index(&tokens), None);
77        assert_eq!(indices.next_index(&tokens), None);
78    }
79
80    #[test]
81    fn set_next_index_jumps_position() {
82        let tokens = TomlTokens::parse("a = 1");
83        let mut indices = TokenIndices::new();
84        indices.set_next_index(2);
85        assert_eq!(indices.next_index(&tokens), Some(2));
86        assert_eq!(indices.next_index(&tokens), Some(3));
87    }
88
89    #[test]
90    fn from_index_begins_at_position() {
91        let tokens = TomlTokens::parse("a = 1");
92        let mut indices = TokenIndices::from_index(2);
93        assert_eq!(indices.next_index(&tokens), Some(2));
94        assert_eq!(indices.next_index(&tokens), Some(3));
95    }
96
97    #[test]
98    fn prev_index_from_start() {
99        let tokens = TomlTokens::parse("key = 1");
100        let mut indices = TokenIndices::new();
101        // At position 0, prev_index should return None
102        assert_eq!(indices.prev_index(&tokens), None);
103    }
104
105    #[test]
106    fn prev_index_after_next() {
107        let tokens = TomlTokens::parse("key = 1");
108        let mut indices = TokenIndices::new();
109        // Advance forward
110        indices.next_index(&tokens);
111        indices.next_index(&tokens);
112        // Now at position 2, prev_index should return Some(1)
113        assert_eq!(indices.prev_index(&tokens), Some(1));
114        assert_eq!(indices.prev_index(&tokens), Some(0));
115        assert_eq!(indices.prev_index(&tokens), None);
116    }
117
118    #[test]
119    fn prev_index_iteration() {
120        let tokens = TomlTokens::parse("[a.b]");
121        let mut indices = TokenIndices::new();
122        // Move to end
123        indices.set_next_index(tokens.len());
124        // Iterate backwards collecting all indices
125        let mut reversed = Vec::new();
126        while let Some(i) = indices.prev_index(&tokens) {
127            reversed.push(i);
128        }
129        let expected: Vec<usize> = (0..tokens.len()).rev().collect();
130        assert_eq!(reversed, expected);
131    }
132}