itertools_wild/adaptors/
mod.rs

1
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}