Correct ExactSizeIterator impl for RepeatedIter

- size_hint must be implemented as described in the docs
- len/size_hint must return the number of items remaining in the iterator, not the size of the container

PiperOrigin-RevId: 604704172
pull/15734/head
Alyssa Haroldsen 10 months ago committed by Copybara-Service
parent 3ccccdb855
commit 398508287e
  1. 9
      rust/repeated.rs
  2. 22
      rust/test/shared/accessors_repeated_test.rs

@ -381,7 +381,6 @@ where
}
}
// TODO: impl ExactSizeIterator
impl<'msg, T> iter::Iterator for RepeatedIter<'msg, T>
where
T: ProxiedInRepeated + ?Sized + 'msg,
@ -395,14 +394,20 @@ where
}
val
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
impl<'msg, T: ?Sized + ProxiedInRepeated> ExactSizeIterator for RepeatedIter<'msg, T> {
fn len(&self) -> usize {
self.view.len()
self.view.len() - self.current_index
}
}
// TODO: impl DoubleEndedIterator
impl<'msg, T: ?Sized + ProxiedInRepeated> FusedIterator for RepeatedIter<'msg, T> {}
impl<'msg, T> iter::IntoIterator for RepeatedView<'msg, T>

@ -68,6 +68,28 @@ macro_rules! generate_repeated_numeric_test {
eq(mutator2.iter().collect::<Vec<_>>())
);
}
#[test]
fn [< test_repeated_ $field _exact_size_iterator >]() {
let mut msg = TestAllTypes::new();
let mut mutator = msg.[<repeated_ $field _mut>]();
for i in 0..5 {
mutator.push(i as $t);
}
let mut iter = mutator.iter();
// size_hint/len must indicate the _remaining_ items in the iterator.
for i in 0..5 {
assert_that!(iter.len(), eq(5 - i));
assert_that!(iter.size_hint(), eq((5 - i, Some(5 - i))));
assert_that!(iter.next(), eq(Some(i as $t)));
}
assert_that!(iter.size_hint(), eq((0, Some(0))));
assert_that!(iter.len(), eq(0));
assert_that!(iter.next(), eq(None));
// Also check FusedIterator - calling `next` multiple times should return `None`.
assert_that!(iter.next(), eq(None));
}
)* }
};
}

Loading…
Cancel
Save