fuel_pest/iterators/
flat_pairs.rs1use alloc::rc::Rc;
11use alloc::vec::Vec;
12use std::fmt;
13use std::sync::Arc;
14
15use super::pair::{self, Pair};
16use super::queueable_token::QueueableToken;
17use super::tokens::{self, Tokens};
18use RuleType;
19
20pub struct FlatPairs<R> {
25 queue: Rc<Vec<QueueableToken<R>>>,
29 input: Arc<str>,
30 start: usize,
31 end: usize,
32}
33
34pub unsafe fn new<R: RuleType>(
38 queue: Rc<Vec<QueueableToken<R>>>,
39 input: Arc<str>,
40 start: usize,
41 end: usize,
42) -> FlatPairs<R> {
43 FlatPairs {
44 queue,
45 input,
46 start,
47 end,
48 }
49}
50
51impl<R: RuleType> FlatPairs<R> {
52 #[inline]
76 pub fn tokens(self) -> Tokens<R> {
77 tokens::new(self.queue, self.input, self.start, self.end)
78 }
79
80 fn next_start(&mut self) {
81 self.start += 1;
82
83 while self.start < self.end && !self.is_start(self.start) {
84 self.start += 1;
85 }
86 }
87
88 fn next_start_from_end(&mut self) {
89 self.end -= 1;
90
91 while self.end >= self.start && !self.is_start(self.end) {
92 self.end -= 1;
93 }
94 }
95
96 fn is_start(&self, index: usize) -> bool {
97 match self.queue[index] {
98 QueueableToken::Start { .. } => true,
99 QueueableToken::End { .. } => false,
100 }
101 }
102}
103
104impl<R: RuleType> Iterator for FlatPairs<R> {
105 type Item = Pair<R>;
106
107 fn next(&mut self) -> Option<Self::Item> {
108 if self.start >= self.end {
109 return None;
110 }
111
112 let pair = unsafe { pair::new(Rc::clone(&self.queue), self.input.clone(), self.start) };
113
114 self.next_start();
115
116 Some(pair)
117 }
118}
119
120impl<R: RuleType> DoubleEndedIterator for FlatPairs<R> {
121 fn next_back(&mut self) -> Option<Self::Item> {
122 if self.end <= self.start {
123 return None;
124 }
125
126 self.next_start_from_end();
127
128 let pair = unsafe { pair::new(Rc::clone(&self.queue), self.input.clone(), self.end) };
129
130 Some(pair)
131 }
132}
133
134impl<R: RuleType> fmt::Debug for FlatPairs<R> {
135 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
136 f.debug_struct("FlatPairs")
137 .field("pairs", &self.clone().collect::<Vec<_>>())
138 .finish()
139 }
140}
141
142impl<R: Clone> Clone for FlatPairs<R> {
143 fn clone(&self) -> FlatPairs<R> {
144 FlatPairs {
145 queue: Rc::clone(&self.queue),
146 input: self.input.clone(),
147 start: self.start,
148 end: self.end,
149 }
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::super::super::macros::tests::*;
156 use super::super::super::Parser;
157 use alloc::vec;
158 use alloc::vec::Vec;
159 use std::sync::Arc;
160
161 #[test]
162 fn iter_for_flat_pairs() {
163 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
164
165 assert_eq!(
166 pairs.flatten().map(|p| p.as_rule()).collect::<Vec<Rule>>(),
167 vec![Rule::a, Rule::b, Rule::c]
168 );
169 }
170
171 #[test]
172 fn double_ended_iter_for_flat_pairs() {
173 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
174 assert_eq!(
175 pairs
176 .flatten()
177 .rev()
178 .map(|p| p.as_rule())
179 .collect::<Vec<Rule>>(),
180 vec![Rule::c, Rule::b, Rule::a]
181 );
182 }
183}