pub struct ConcatenatedIter<I: Iterator> {
iters: Vec<I>,
current_iter_index: usize,
}
impl<I: Iterator> ConcatenatedIter<I> {
pub fn from_iters(iters: Vec<I>) -> Self {
ConcatenatedIter {
iters,
current_iter_index: 0,
}
}
pub fn concat_iter(self, other: I) -> Self {
let mut iters = self.iters;
iters.push(other);
ConcatenatedIter {
iters,
current_iter_index: self.current_iter_index,
}
}
}
impl<I: Iterator> From<Vec<I>> for ConcatenatedIter<I> {
fn from(iters: Vec<I>) -> Self {
Self::from_iters(iters)
}
}
impl<I: Iterator> Iterator for ConcatenatedIter<I> {
type Item = <I as Iterator>::Item;
fn next(&mut self) -> Option<Self::Item> {
match self.iters.get_mut(self.current_iter_index) {
None => None,
Some(iter) => match iter.next() {
Some(x) => Some(x),
None => {
self.current_iter_index += 1;
self.next()
}
},
}
}
}
pub trait IntoConcatIter: Iterator + Sized {
fn into_concat_iter(self, other: Self) -> ConcatenatedIter<Self> {
ConcatenatedIter {
iters: vec![self, other],
current_iter_index: 0,
}
}
}
impl<I: Iterator + Sized> IntoConcatIter for I {}
#[cfg(test)]
mod tests {
use crate::iter::{concatenated_iter::IntoConcatIter, ConcatenatedIter};
use std::collections::BTreeMap;
#[test]
fn test_from_iters() {
let arr1 = vec![0, 1, 2];
let arr2 = vec![3, 4];
let arr3 = vec![5, 6];
let mut concat_iter =
ConcatenatedIter::from(vec![arr1.iter(), arr2.iter(), arr3.iter()]);
assert_eq!(concat_iter.next(), Some(&0));
assert_eq!(concat_iter.next(), Some(&1));
assert_eq!(concat_iter.next(), Some(&2));
assert_eq!(concat_iter.next(), Some(&3));
assert_eq!(concat_iter.next(), Some(&4));
assert_eq!(concat_iter.next(), Some(&5));
assert_eq!(concat_iter.next(), Some(&6));
assert_eq!(concat_iter.next(), None);
}
#[test]
fn test_concat_vec_iter() {
let arr1 = vec![0, 1, 2];
let arr2 = vec![3, 4];
let arr3 = vec![6, 7, 8];
{
let mut concat_1_2 = arr1.iter().into_concat_iter(arr2.iter());
assert_eq!(concat_1_2.next(), Some(&0));
assert_eq!(concat_1_2.next(), Some(&1));
assert_eq!(concat_1_2.next(), Some(&2));
assert_eq!(concat_1_2.next(), Some(&3));
assert_eq!(concat_1_2.next(), Some(&4));
assert_eq!(concat_1_2.next(), None);
}
{
let mut concat_1_2 = arr1.iter().into_concat_iter(arr2.iter());
assert_eq!(concat_1_2.next(), Some(&0));
assert_eq!(concat_1_2.next(), Some(&1));
concat_1_2 = concat_1_2.concat_iter(arr3.iter());
assert_eq!(concat_1_2.next(), Some(&2));
assert_eq!(concat_1_2.next(), Some(&3));
assert_eq!(concat_1_2.next(), Some(&4));
assert_eq!(concat_1_2.next(), Some(&6));
assert_eq!(concat_1_2.next(), Some(&7));
concat_1_2 = concat_1_2.concat_iter(arr3.iter());
assert_eq!(concat_1_2.next(), Some(&8));
assert_eq!(concat_1_2.next(), Some(&6));
assert_eq!(concat_1_2.next(), Some(&7));
assert_eq!(concat_1_2.next(), Some(&8));
concat_1_2 = concat_1_2.concat_iter(arr1.iter());
assert_eq!(concat_1_2.next(), Some(&0));
assert_eq!(concat_1_2.next(), Some(&1));
assert_eq!(concat_1_2.next(), Some(&2));
assert_eq!(concat_1_2.next(), None);
}
}
#[test]
fn test_concat_btreemap_iter() {
let m1: BTreeMap<i32, i32> = vec![(1, 2), (3, 4)].into_iter().collect();
let m2: BTreeMap<i32, i32> =
vec![(11, 12), (13, 14), (15, 16)].into_iter().collect();
let mut iter = m1.iter().into_concat_iter(m2.iter());
assert_eq!(iter.next(), Some((&1, &2)));
assert_eq!(iter.next(), Some((&3, &4)));
assert_eq!(iter.next(), Some((&11, &12)));
assert_eq!(iter.next(), Some((&13, &14)));
assert_eq!(iter.next(), Some((&15, &16)));
}
}