1use alloc::rc::Rc;
11use alloc::vec::Vec;
12use core::fmt;
13
14use super::line_index::LineIndex;
15use super::pair::{self, Pair};
16use super::queueable_token::QueueableToken;
17use super::tokens::{self, Tokens};
18use crate::RuleType;
19
20pub struct FlatPairs<'i, R> {
25 queue: Rc<Vec<QueueableToken<'i, R>>>,
26 input: &'i str,
27 start: usize,
28 end: usize,
29 line_index: Rc<LineIndex>,
30}
31
32pub fn new<'i, R: RuleType>(
33 queue: Rc<Vec<QueueableToken<'i, R>>>,
34 input: &'i str,
35 line_index: Rc<LineIndex>,
36 start: usize,
37 end: usize,
38) -> FlatPairs<'i, R> {
39 FlatPairs {
40 queue,
41 input,
42 line_index,
43 start,
44 end,
45 }
46}
47
48impl<'i, R: RuleType> FlatPairs<'i, R> {
49 #[inline]
72 pub fn tokens(self) -> Tokens<'i, R> {
73 tokens::new(self.queue, self.input, self.start, self.end)
74 }
75
76 fn next_start(&mut self) {
77 self.start += 1;
78
79 while self.start < self.end && !self.is_start(self.start) {
80 self.start += 1;
81 }
82 }
83
84 fn next_start_from_end(&mut self) {
85 self.end -= 1;
86
87 while self.end >= self.start && !self.is_start(self.end) {
88 self.end -= 1;
89 }
90 }
91
92 fn is_start(&self, index: usize) -> bool {
93 match self.queue[index] {
94 QueueableToken::Start { .. } => true,
95 QueueableToken::End { .. } => false,
96 }
97 }
98}
99
100impl<'i, R: RuleType> ExactSizeIterator for FlatPairs<'i, R> {
101 fn len(&self) -> usize {
102 (self.end - self.start) >> 1
104 }
105}
106
107impl<'i, R: RuleType> Iterator for FlatPairs<'i, R> {
108 type Item = Pair<'i, R>;
109
110 fn next(&mut self) -> Option<Self::Item> {
111 if self.start >= self.end {
112 return None;
113 }
114
115 let pair = pair::new(
116 Rc::clone(&self.queue),
117 self.input,
118 Rc::clone(&self.line_index),
119 self.start,
120 );
121 self.next_start();
122
123 Some(pair)
124 }
125
126 fn size_hint(&self) -> (usize, Option<usize>) {
127 let len = <Self as ExactSizeIterator>::len(self);
128 (len, Some(len))
129 }
130}
131
132impl<'i, R: RuleType> DoubleEndedIterator for FlatPairs<'i, R> {
133 fn next_back(&mut self) -> Option<Self::Item> {
134 if self.end <= self.start {
135 return None;
136 }
137
138 self.next_start_from_end();
139
140 let pair = pair::new(
141 Rc::clone(&self.queue),
142 self.input,
143 Rc::clone(&self.line_index),
144 self.end,
145 );
146
147 Some(pair)
148 }
149}
150
151impl<'i, R: RuleType> fmt::Debug for FlatPairs<'i, R> {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 f.debug_struct("FlatPairs")
154 .field("pairs", &self.clone().collect::<Vec<_>>())
155 .finish()
156 }
157}
158
159impl<'i, R: Clone> Clone for FlatPairs<'i, R> {
160 fn clone(&self) -> FlatPairs<'i, R> {
161 FlatPairs {
162 queue: Rc::clone(&self.queue),
163 input: self.input,
164 line_index: Rc::clone(&self.line_index),
165 start: self.start,
166 end: self.end,
167 }
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use super::super::super::macros::tests::*;
174 use super::super::super::Parser;
175 use alloc::vec;
176 use alloc::vec::Vec;
177
178 #[test]
179 fn iter_for_flat_pairs() {
180 let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
181
182 assert_eq!(
183 pairs.flatten().map(|p| p.as_rule()).collect::<Vec<Rule>>(),
184 vec![Rule::a, Rule::b, Rule::c]
185 );
186 }
187
188 #[test]
189 fn double_ended_iter_for_flat_pairs() {
190 let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
191 assert_eq!(
192 pairs
193 .flatten()
194 .rev()
195 .map(|p| p.as_rule())
196 .collect::<Vec<Rule>>(),
197 vec![Rule::c, Rule::b, Rule::a]
198 );
199 }
200
201 #[test]
202 fn test_line_col() {
203 let mut pairs = AbcParser::parse(Rule::a, "abcNe\nabcde").unwrap().flatten();
204
205 let pair = pairs.next().unwrap();
206 assert_eq!(pair.as_str(), "abc");
207 assert_eq!(pair.line_col(), (1, 1));
208 assert_eq!(pair.line_col(), pair.as_span().start_pos().line_col());
209
210 let pair = pairs.next().unwrap();
211 assert_eq!(pair.as_str(), "b");
212 assert_eq!(pair.line_col(), (1, 2));
213 assert_eq!(pair.line_col(), pair.as_span().start_pos().line_col());
214
215 let pair = pairs.next().unwrap();
216 assert_eq!(pair.as_str(), "e");
217 assert_eq!(pair.line_col(), (1, 5));
218 assert_eq!(pair.line_col(), pair.as_span().start_pos().line_col());
219 }
220
221 #[test]
222 fn exact_size_iter_for_pairs() {
223 let pairs = AbcParser::parse(Rule::a, "abc\nefgh").unwrap().flatten();
224 assert_eq!(pairs.len(), pairs.count());
225
226 let pairs = AbcParser::parse(Rule::a, "我很漂亮efgh").unwrap().flatten();
227 assert_eq!(pairs.len(), pairs.count());
228
229 let pairs = AbcParser::parse(Rule::a, "abc\nefgh").unwrap().flatten();
230 let pairs = pairs.rev();
231 assert_eq!(pairs.len(), pairs.count());
232
233 let mut pairs = AbcParser::parse(Rule::a, "abc\nefgh").unwrap().flatten();
234 let pairs_len = pairs.len();
235 let _ = pairs.next().unwrap();
236 assert_eq!(pairs.count() + 1, pairs_len);
237 }
238}