use crate::LogProgressBar;
pub struct LogProgressIterator<I> {
inner: I,
progress: LogProgressBar,
}
impl<I> LogProgressIterator<I> {
fn new(inner: I, progress: LogProgressBar) -> Self {
Self { inner, progress }
}
}
impl<I: Iterator> Iterator for LogProgressIterator<I> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
match self.inner.next() {
Some(item) => {
self.progress.inc(1);
Some(item)
}
None => {
self.progress.finish();
None
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<I: ExactSizeIterator> ExactSizeIterator for LogProgressIterator<I> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<I: DoubleEndedIterator> DoubleEndedIterator for LogProgressIterator<I> {
fn next_back(&mut self) -> Option<Self::Item> {
match self.inner.next_back() {
Some(item) => {
self.progress.inc(1);
Some(item)
}
None => {
self.progress.finish();
None
}
}
}
}
pub trait ProgressIteratorExt: Iterator + Sized {
fn progress_with(self, len: usize, name: &str) -> LogProgressIterator<Self> {
let progress = LogProgressBar::new(len, name);
LogProgressIterator::new(self, progress)
}
fn progress(self, name: &str) -> LogProgressIterator<Self>
where
Self: ExactSizeIterator,
{
let len = self.len();
let progress = LogProgressBar::new(len, name);
LogProgressIterator::new(self, progress)
}
}
impl<I: Iterator> ProgressIteratorExt for I {}