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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
// SPDX-License-Identifier: MIT
// Copyright 2024 IROX Contributors
//
//!
//! Iterators adds the [`Itertools`] Trait, which adds a number of additional
//! helper methods to the [`Iterator`] Trait.
//!
use self::join::Joining;
use self::looping_forever::LoopingForever;
extern crate alloc;
use crate::iterators::join::MultiJoining;
use alloc::vec::Vec;
mod join;
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
}
///
/// Returns the elements in this iterator interspersed with the joining delimiter.
/// For example, if this iterator contains `[A, B, C, D]` and the delimiter is `z`, then the
/// final iteration sequence will be `[A, z, B, z, C, z, D]`
#[must_use]
fn joining(self, delim: Self::Item) -> Joining<Self, Self::Item>
where
Self: Sized,
Self::Item: Clone,
{
Joining::new(self, delim)
}
///
/// Returns the elements in this iterator interspersed with the elements in the joining delimeter.
/// For example, if this iterator contains `[A, B, C, D]` and the delimiters are `[1, 2]`, then
/// the final iteration sequence will be `[A, 1, 2, B, 1, 2, C, 1, 2, D]`
#[must_use]
fn joining_multi(self, delim: &[Self::Item]) -> MultiJoining<Self, Self::Item>
where
Self: Sized,
Self::Item: Clone,
{
MultiJoining::new(self, delim)
}
}
impl<T: ?Sized> Itertools for T where T: Iterator {}