diff options
Diffstat (limited to 'src/iterators/flat_pairs.rs')
-rw-r--r-- | src/iterators/flat_pairs.rs | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/src/iterators/flat_pairs.rs b/src/iterators/flat_pairs.rs index 52a2074..9b92f55 100644 --- a/src/iterators/flat_pairs.rs +++ b/src/iterators/flat_pairs.rs @@ -25,7 +25,7 @@ pub struct FlatPairs<'i, R> { /// # Safety /// /// All `QueueableToken`s' `input_pos` must be valid character boundary indices into `input`. - queue: Rc<Vec<QueueableToken<R>>>, + queue: Rc<Vec<QueueableToken<'i, R>>>, input: &'i str, start: usize, end: usize, @@ -35,12 +35,12 @@ pub struct FlatPairs<'i, R> { /// # Safety /// /// All `QueueableToken`s' `input_pos` must be valid character boundary indices into `input`. -pub unsafe fn new<R: RuleType>( - queue: Rc<Vec<QueueableToken<R>>>, - input: &str, +pub unsafe fn new<'i, R: RuleType>( + queue: Rc<Vec<QueueableToken<'i, R>>>, + input: &'i str, start: usize, end: usize, -) -> FlatPairs<'_, R> { +) -> FlatPairs<'i, R> { FlatPairs { queue, input, @@ -102,6 +102,13 @@ impl<'i, R: RuleType> FlatPairs<'i, R> { } } +impl<'i, R: RuleType> ExactSizeIterator for FlatPairs<'i, R> { + fn len(&self) -> usize { + // Tokens len is exactly twice as flatten pairs len + (self.end - self.start) >> 1 + } +} + impl<'i, R: RuleType> Iterator for FlatPairs<'i, R> { type Item = Pair<'i, R>; @@ -122,6 +129,11 @@ impl<'i, R: RuleType> Iterator for FlatPairs<'i, R> { Some(pair) } + + fn size_hint(&self) -> (usize, Option<usize>) { + let len = <Self as ExactSizeIterator>::len(self); + (len, Some(len)) + } } impl<'i, R: RuleType> DoubleEndedIterator for FlatPairs<'i, R> { @@ -214,4 +226,22 @@ mod tests { assert_eq!(pair.line_col(), (1, 5)); assert_eq!(pair.line_col(), pair.as_span().start_pos().line_col()); } + + #[test] + fn exact_size_iter_for_pairs() { + let pairs = AbcParser::parse(Rule::a, "abc\nefgh").unwrap().flatten(); + assert_eq!(pairs.len(), pairs.count()); + + let pairs = AbcParser::parse(Rule::a, "我很漂亮efgh").unwrap().flatten(); + assert_eq!(pairs.len(), pairs.count()); + + let pairs = AbcParser::parse(Rule::a, "abc\nefgh").unwrap().flatten(); + let pairs = pairs.rev(); + assert_eq!(pairs.len(), pairs.count()); + + let mut pairs = AbcParser::parse(Rule::a, "abc\nefgh").unwrap().flatten(); + let pairs_len = pairs.len(); + let _ = pairs.next().unwrap(); + assert_eq!(pairs.count() + 1, pairs_len); + } } |