Coverage Report

Created: 2025-10-10 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/itertools-0.12.1/src/pad_tail.rs
Line
Count
Source
1
use crate::size_hint;
2
use std::iter::{Fuse, FusedIterator};
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()`](crate::Itertools::pad_using) for more information.
10
#[derive(Clone)]
11
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
12
pub struct PadUsing<I, F> {
13
    iter: Fuse<I>,
14
    min: usize,
15
    pos: usize,
16
    filler: F,
17
}
18
19
impl<I, F> std::fmt::Debug for PadUsing<I, F>
20
where
21
    I: std::fmt::Debug,
22
{
23
    debug_fmt_fields!(PadUsing, iter, min, pos);
24
}
25
26
/// Create a new `PadUsing` iterator.
27
0
pub fn pad_using<I, F>(iter: I, min: usize, filler: F) -> PadUsing<I, F>
28
0
where
29
0
    I: Iterator,
30
0
    F: FnMut(usize) -> I::Item,
31
{
32
0
    PadUsing {
33
0
        iter: iter.fuse(),
34
0
        min,
35
0
        pos: 0,
36
0
        filler,
37
0
    }
38
0
}
39
40
impl<I, F> Iterator for PadUsing<I, F>
41
where
42
    I: Iterator,
43
    F: FnMut(usize) -> I::Item,
44
{
45
    type Item = I::Item;
46
47
    #[inline]
48
0
    fn next(&mut self) -> Option<Self::Item> {
49
0
        match self.iter.next() {
50
            None => {
51
0
                if self.pos < self.min {
52
0
                    let e = Some((self.filler)(self.pos));
53
0
                    self.pos += 1;
54
0
                    e
55
                } else {
56
0
                    None
57
                }
58
            }
59
0
            e => {
60
0
                self.pos += 1;
61
0
                e
62
            }
63
        }
64
0
    }
65
66
0
    fn size_hint(&self) -> (usize, Option<usize>) {
67
0
        let tail = self.min.saturating_sub(self.pos);
68
0
        size_hint::max(self.iter.size_hint(), (tail, Some(tail)))
69
0
    }
70
71
0
    fn fold<B, G>(self, mut init: B, mut f: G) -> B
72
0
    where
73
0
        G: FnMut(B, Self::Item) -> B,
74
    {
75
0
        let mut pos = self.pos;
76
0
        init = self.iter.fold(init, |acc, item| {
77
0
            pos += 1;
78
0
            f(acc, item)
79
0
        });
80
0
        (pos..self.min).map(self.filler).fold(init, f)
81
0
    }
82
}
83
84
impl<I, F> DoubleEndedIterator for PadUsing<I, F>
85
where
86
    I: DoubleEndedIterator + ExactSizeIterator,
87
    F: FnMut(usize) -> I::Item,
88
{
89
0
    fn next_back(&mut self) -> Option<Self::Item> {
90
0
        if self.min == 0 {
91
0
            self.iter.next_back()
92
0
        } else if self.iter.len() >= self.min {
93
0
            self.min -= 1;
94
0
            self.iter.next_back()
95
        } else {
96
0
            self.min -= 1;
97
0
            Some((self.filler)(self.min))
98
        }
99
0
    }
100
101
0
    fn rfold<B, G>(self, mut init: B, mut f: G) -> B
102
0
    where
103
0
        G: FnMut(B, Self::Item) -> B,
104
    {
105
0
        init = (self.iter.len()..self.min)
106
0
            .map(self.filler)
107
0
            .rfold(init, &mut f);
108
0
        self.iter.rfold(init, f)
109
0
    }
110
}
111
112
impl<I, F> ExactSizeIterator for PadUsing<I, F>
113
where
114
    I: ExactSizeIterator,
115
    F: FnMut(usize) -> I::Item,
116
{
117
}
118
119
impl<I, F> FusedIterator for PadUsing<I, F>
120
where
121
    I: FusedIterator,
122
    F: FnMut(usize) -> I::Item,
123
{
124
}