summaryrefslogtreecommitdiff
path: root/src/iterators/flat_pairs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/iterators/flat_pairs.rs')
-rw-r--r--src/iterators/flat_pairs.rs40
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);
+ }
}