xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/itertools-0.11.0/src/pad_tail.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 use std::iter::{Fuse, FusedIterator};
2 use crate::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()`](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.
pad_using<I, F>(iter: I, min: usize, filler: F) -> PadUsing<I, F> where I: Iterator, F: FnMut(usize) -> I::Item27 pub fn pad_using<I, F>(iter: I, min: usize, filler: F) -> PadUsing<I, F>
28     where I: Iterator,
29           F: FnMut(usize) -> I::Item
30 {
31     PadUsing {
32         iter: iter.fuse(),
33         min,
34         pos: 0,
35         filler,
36     }
37 }
38 
39 impl<I, F> Iterator for PadUsing<I, F>
40     where I: Iterator,
41           F: FnMut(usize) -> I::Item
42 {
43     type Item = I::Item;
44 
45     #[inline]
next(&mut self) -> Option<Self::Item>46     fn next(&mut self) -> Option<Self::Item> {
47         match self.iter.next() {
48             None => {
49                 if self.pos < self.min {
50                     let e = Some((self.filler)(self.pos));
51                     self.pos += 1;
52                     e
53                 } else {
54                     None
55                 }
56             },
57             e => {
58                 self.pos += 1;
59                 e
60             }
61         }
62     }
63 
size_hint(&self) -> (usize, Option<usize>)64     fn size_hint(&self) -> (usize, Option<usize>) {
65         let tail = self.min.saturating_sub(self.pos);
66         size_hint::max(self.iter.size_hint(), (tail, Some(tail)))
67     }
68 }
69 
70 impl<I, F> DoubleEndedIterator for PadUsing<I, F>
71     where I: DoubleEndedIterator + ExactSizeIterator,
72           F: FnMut(usize) -> I::Item
73 {
next_back(&mut self) -> Option<Self::Item>74     fn next_back(&mut self) -> Option<Self::Item> {
75         if self.min == 0 {
76             self.iter.next_back()
77         } else if self.iter.len() >= self.min {
78             self.min -= 1;
79             self.iter.next_back()
80         } else {
81             self.min -= 1;
82             Some((self.filler)(self.min))
83         }
84     }
85 }
86 
87 impl<I, F> ExactSizeIterator for PadUsing<I, F>
88     where I: ExactSizeIterator,
89           F: FnMut(usize) -> I::Item
90 {}
91 
92 
93 impl<I, F> FusedIterator for PadUsing<I, F>
94     where I: FusedIterator,
95           F: FnMut(usize) -> I::Item
96 {}
97