itertools_wild/adaptors/
mod.rs1
2
3use std::iter::Fuse;
4
5pub struct ClampToExactLength<I, F> {
6 pub(crate) iter: Fuse<I>,
7 pub(crate) filler: F,
8 pub(crate) index: usize,
9 pub(crate) size: usize,
10}
11
12impl<I, F> Iterator for ClampToExactLength<I, F>
13 where I: Iterator,
14 F: FnMut(usize) -> I::Item,
15{
16 type Item = I::Item;
17
18 fn next(&mut self) -> Option<Self::Item> {
19 if self.index >= self.size {
20 None
21 } else {
22 let index = self.index;
23 self.index += 1;
24 match self.iter.next() {
25 None => Some((self.filler)(index)),
26 elt => elt,
27 }
28 }
29 }
30
31 fn size_hint(&self) -> (usize, Option<usize>) {
32 let len = self.size - self.index;
33 (len, Some(len))
34 }
35}
36
37
38pub struct AssertExactSize<I> {
39 pub(crate) iter: I,
40 pub(crate) size: usize,
41}
42
43impl<I> AssertExactSize<I>
44 where I: Iterator,
45{
46 fn get_next<F>(&mut self, next: F) -> Option<I::Item>
47 where F: FnOnce(&mut I) -> Option<I::Item>
48 {
49 let elt = next(&mut self.iter);
50 if let Some(_) = elt {
51 debug_assert!(self.size > 0, "AssertExactSize: length mismatch, iterator\
52 produced at least one element more than the asserted size");
53 self.size -= 1;
54 } else {
55 debug_assert_eq!(0, self.size, "AssertExactSize: length mismatch, iterator\
56 produced {} elements less than the asserted size", self.size);
57 }
58 elt
59 }
60}
61
62impl<I> Iterator for AssertExactSize<I> where I: Iterator
63{
64 type Item = I::Item;
65 fn next(&mut self) -> Option<Self::Item> {
66 self.get_next(|iter| iter.next())
67 }
68
69 fn size_hint(&self) -> (usize, Option<usize>) {
70 (self.size, Some(self.size))
71 }
72}
73
74impl<I> ExactSizeIterator for AssertExactSize<I> where I: Iterator { }
75impl<I> DoubleEndedIterator for AssertExactSize<I>
76 where I: DoubleEndedIterator
77{
78 fn next_back(&mut self) -> Option<Self::Item> {
79 self.get_next(|iter| iter.next_back())
80 }
81
82}