]> git.proxmox.com Git - rustc.git/blame - vendor/itertools-0.8.2/src/pad_tail.rs
New upstream version 1.47.0+dfsg1
[rustc.git] / vendor / itertools-0.8.2 / src / pad_tail.rs
CommitLineData
532ac7d7
XL
1use std::iter::Fuse;
2use size_hint;
3
4/// An iterator adaptor that pads a sequence to a minimum length by filling
5/// missing elements using a closure.
6///
7/// Iterator element type is `I::Item`.
8///
9/// See [`.pad_using()`](../trait.Itertools.html#method.pad_using) for more information.
10#[derive(Clone)]
11#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
12pub struct PadUsing<I, F> {
13 iter: Fuse<I>,
14 min: usize,
15 pos: usize,
16 filler: F,
17}
18
19/// Create a new **PadUsing** iterator.
20pub fn pad_using<I, F>(iter: I, min: usize, filler: F) -> PadUsing<I, F>
21 where I: Iterator,
22 F: FnMut(usize) -> I::Item
23{
24 PadUsing {
25 iter: iter.fuse(),
26 min: min,
27 pos: 0,
28 filler: filler,
29 }
30}
31
32impl<I, F> Iterator for PadUsing<I, F>
33 where I: Iterator,
34 F: FnMut(usize) -> I::Item
35{
36 type Item = I::Item;
37
38 #[inline]
39 fn next(&mut self) -> Option<I::Item> {
40 match self.iter.next() {
41 None => {
42 if self.pos < self.min {
43 let e = Some((self.filler)(self.pos));
44 self.pos += 1;
45 e
46 } else {
47 None
48 }
49 },
50 e => {
51 self.pos += 1;
52 e
53 }
54 }
55 }
56
57 fn size_hint(&self) -> (usize, Option<usize>) {
58 let tail = self.min.saturating_sub(self.pos);
59 size_hint::max(self.iter.size_hint(), (tail, Some(tail)))
60 }
61}
62
63impl<I, F> DoubleEndedIterator for PadUsing<I, F>
64 where I: DoubleEndedIterator + ExactSizeIterator,
65 F: FnMut(usize) -> I::Item
66{
67 fn next_back(&mut self) -> Option<I::Item> {
68 if self.min == 0 {
69 self.iter.next_back()
70 } else if self.iter.len() >= self.min {
71 self.min -= 1;
72 self.iter.next_back()
73 } else {
74 self.min -= 1;
75 Some((self.filler)(self.min))
76 }
77 }
78}
79
80impl<I, F> ExactSizeIterator for PadUsing<I, F>
81 where I: ExactSizeIterator,
82 F: FnMut(usize) -> I::Item
83{}