#![no_std]
#![doc = include_str!("../README.md")]
extern crate alloc;
use core::ops::{Deref, DerefMut};
use alloc::{vec, vec::Vec};
#[derive(Debug, Clone)]
pub struct VecIter<I: Iterator> {
iter: I,
collected: Vec<I::Item>,
}
impl<I: Iterator> Deref for VecIter<I> {
type Target = [I::Item];
fn deref(&self) -> &Self::Target {
&self.collected
}
}
impl<I: Iterator> DerefMut for VecIter<I> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.collected
}
}
impl<I: Iterator> Iterator for VecIter<I>
where I::Item: Clone,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
let elem = self.iter.next()?;
self.init_capacity_push(elem.clone());
Some(elem)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let elem = self.iter.next()?;
self.init_capacity_push(elem);
for _ in 1..n {
self.collected.push(self.iter.next()?);
}
self.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (lo, hi) = self.iter.size_hint();
(lo+self.collected_len(), hi.map(|hi| hi+self.collected_len()))
}
fn fold<B, F>(self, init: B, f: F) -> B
where Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.collected.into_iter().chain(self.iter).fold(init, f)
}
}
impl<I: Iterator> VecIter<I>
where I::Item: Clone,
{
fn init_capacity(&mut self) {
if self.collected_len() == 0 {
self.collected.reserve(self.size_hint().0);
}
}
fn init_capacity_push(&mut self, value: I::Item) {
if self.collected_len() == 0 {
self.collected.reserve(self.size_hint().0+1);
}
self.collected.push(value);
}
fn require(&mut self, i: usize) -> Option<&mut I::Item> {
self.init_capacity();
let n = i.saturating_sub(self.collected_len())+1;
self.collected.extend(self.iter.by_ref().take(n));
self.collected.get_mut(i)
}
#[inline]
pub fn collected_len(&self) -> usize {
self.collected.len()
}
pub fn get_req(&mut self, i: usize) -> Option<&I::Item> {
self.require(i).map(|value| &*value)
}
pub fn get_req_mut(&mut self, i: usize) -> Option<&mut I::Item> {
self.require(i)
}
pub fn get_req_cloned(&mut self, i: usize) -> Option<I::Item> {
self.require(i).cloned()
}
pub fn into_all_collected(mut self) -> Vec<I::Item> {
self.collected.extend(self.iter);
self.collected
}
}
impl<I: Iterator + Default> Default for VecIter<I> {
fn default() -> Self {
Self {
iter: I::default(),
collected: vec![],
}
}
}
#[doc = include_str!("../README.md")]
pub trait IterVecIterExt: Iterator + Sized {
fn vec_iter(self) -> VecIter<Self> {
VecIter { iter: self, collected: vec![] }
}
}
impl<I: Iterator> IterVecIterExt for I { }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic_each() {
assert_eq!((0..5).vec_iter().collect::<Vec<_>>(), vec![0, 1, 2, 3, 4]);
assert_eq!((0..0).vec_iter().collect::<Vec<_>>(), vec![]);
}
#[test]
fn capacity() {
let mut iter = (0..5).vec_iter();
assert_eq!(iter.collected.capacity(), 0);
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.collected.capacity(), 5);
assert_eq!(iter.collected_len(), 1);
}
#[test]
fn nth() {
let mut iter = (0..5).vec_iter();
assert_eq!(iter.collected.capacity(), 0);
assert_eq!(iter.nth(2), Some(2));
assert_eq!(iter.collected.capacity(), 5);
assert_eq!(*iter, [0, 1, 2]);
assert_eq!(iter.next(), Some(3));
}
#[test]
fn into_all_collected() {
let mut iter = (0..5).vec_iter();
assert_eq!(iter.collected.capacity(), 0);
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.collected.capacity(), 5);
assert_eq!(iter.collected_len(), 1);
assert_eq!(iter.into_all_collected(), vec![0, 1, 2, 3, 4]);
}
#[test]
fn get_req() {
let mut iter = (0..5).vec_iter();
assert_eq!(iter.collected.capacity(), 0);
assert_eq!(iter.get_req_cloned(2), Some(2));
assert_eq!(iter.collected.capacity(), 5);
assert_eq!(iter.collected_len(), 3);
assert_eq!(iter.into_all_collected(), vec![0, 1, 2, 3, 4]);
}
}