diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/itertools/src/pad_tail.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/itertools/src/pad_tail.rs')
-rw-r--r-- | third_party/rust/itertools/src/pad_tail.rs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/third_party/rust/itertools/src/pad_tail.rs b/third_party/rust/itertools/src/pad_tail.rs new file mode 100644 index 0000000000..248a432436 --- /dev/null +++ b/third_party/rust/itertools/src/pad_tail.rs @@ -0,0 +1,96 @@ +use std::iter::{Fuse, FusedIterator}; +use crate::size_hint; + +/// An iterator adaptor that pads a sequence to a minimum length by filling +/// missing elements using a closure. +/// +/// Iterator element type is `I::Item`. +/// +/// See [`.pad_using()`](crate::Itertools::pad_using) for more information. +#[derive(Clone)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +pub struct PadUsing<I, F> { + iter: Fuse<I>, + min: usize, + pos: usize, + filler: F, +} + +impl<I, F> std::fmt::Debug for PadUsing<I, F> +where + I: std::fmt::Debug, +{ + debug_fmt_fields!(PadUsing, iter, min, pos); +} + +/// Create a new `PadUsing` iterator. +pub fn pad_using<I, F>(iter: I, min: usize, filler: F) -> PadUsing<I, F> + where I: Iterator, + F: FnMut(usize) -> I::Item +{ + PadUsing { + iter: iter.fuse(), + min, + pos: 0, + filler, + } +} + +impl<I, F> Iterator for PadUsing<I, F> + where I: Iterator, + F: FnMut(usize) -> I::Item +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option<Self::Item> { + match self.iter.next() { + None => { + if self.pos < self.min { + let e = Some((self.filler)(self.pos)); + self.pos += 1; + e + } else { + None + } + }, + e => { + self.pos += 1; + e + } + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + let tail = self.min.saturating_sub(self.pos); + size_hint::max(self.iter.size_hint(), (tail, Some(tail))) + } +} + +impl<I, F> DoubleEndedIterator for PadUsing<I, F> + where I: DoubleEndedIterator + ExactSizeIterator, + F: FnMut(usize) -> I::Item +{ + fn next_back(&mut self) -> Option<Self::Item> { + if self.min == 0 { + self.iter.next_back() + } else if self.iter.len() >= self.min { + self.min -= 1; + self.iter.next_back() + } else { + self.min -= 1; + Some((self.filler)(self.min)) + } + } +} + +impl<I, F> ExactSizeIterator for PadUsing<I, F> + where I: ExactSizeIterator, + F: FnMut(usize) -> I::Item +{} + + +impl<I, F> FusedIterator for PadUsing<I, F> + where I: FusedIterator, + F: FnMut(usize) -> I::Item +{} |