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