1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
// SPDX-License-Identifier: MIT
// Copyright 2023 IROX Contributors
//!
//! Iterators adds the [`Itertools`] Trait, which adds a number of additional
//! helper methods to the [`Iterator`] Trait.
//!
use self::looping_forever::LoopingForever;
extern crate alloc;
use alloc::vec::Vec;
pub mod looping_forever;
///
/// Itertools adds helpful additional methods to [`Iterator`]
pub trait Itertools: Iterator {
///
/// Returns an iterator that never ends, sequentially looping over all items in this
/// iterator forever, unless there are no items in the iterator.
fn looping_forever(self) -> LoopingForever<Self::Item>
where
Self: Sized + Iterator,
Self::Item: Clone,
{
LoopingForever {
index: 0,
items: self.collect(),
}
}
///
/// Collects a specific amount of items from the iterator. The underlying iterator may return
/// more, or less items than the specified count. Any remaining uncollected items will be
/// discarded. If count is greater than the length of the underlying iterator, then the
/// remainder of the returned vector will be None.
#[must_use]
fn collect_exact(mut self, count: usize) -> Vec<Option<Self::Item>>
where
Self: Sized + Iterator,
Self::Item: Clone,
{
let mut out: Vec<Option<Self::Item>> = Vec::with_capacity(count);
for _i in 0..count {
out.push(self.next())
}
out
}
///
/// Same behavior as [`Itertools::collect_exact`], except rather than returning 'None' after the end, it
/// returns the specified value
#[must_use]
fn collect_exact_or(mut self, count: usize, def: Self::Item) -> Vec<Self::Item>
where
Self: Sized + Iterator,
Self::Item: Clone,
{
let mut out: Vec<Self::Item> = Vec::with_capacity(count);
for _i in 0..count {
out.push(self.next().unwrap_or(def.clone()))
}
out
}
///
/// Same behavior as [`Itertools::collect_exact`], except rather than returning 'None' after the end, it
/// returns the default value
#[must_use]
fn collect_exact_or_default(mut self, count: usize) -> Vec<Self::Item>
where
Self: Sized + Iterator,
Self::Item: Clone + Default,
{
let mut out: Vec<Self::Item> = Vec::with_capacity(count);
for _i in 0..count {
out.push(self.next().unwrap_or_default());
}
out
}
///
/// Collects and returns upto 'count' items from this iterator. If this
/// iterator is exhausted, the returned vector is empty. Note, the returned
/// vector may have *up to* the requested number of items if the iterator
/// exhausts before filling the chunk.
#[must_use]
fn collect_next_chunk(&mut self, count: usize) -> Vec<Self::Item> {
let mut out: Vec<Self::Item> = Vec::with_capacity(count);
for _i in 0..count {
match self.next() {
Some(e) => out.push(e),
None => break,
}
}
out
}
}
impl<T: ?Sized> Itertools for T where T: Iterator {}