pub struct VecAltern<'a, A> {
iters: Vec<Box<dyn Iterator<Item = A> + 'a>>,
current: usize,
}
impl<'a, A> VecAltern<'a, A> {
pub fn new() -> Self {
Self {
iters: vec![],
current: 0,
}
}
pub fn with_capacity(capacity : usize) -> Self {
Self {
iters: Vec::with_capacity(capacity),
current: 0
}
}
pub fn add_and(mut self, iterator: impl Iterator<Item = A> + 'a) -> Self {
self.iters.push(Box::new(iterator));
self
}
pub fn add(&mut self, iterator: impl Iterator<Item = A> + 'a){
self.iters.push(Box::new(iterator));
}
}
impl<'a, A> Iterator for VecAltern<'a, A>
{
type Item = A;
fn next(&mut self) -> Option<A> {
loop {
if self.iters.is_empty() {
return None;
} else {
let next;
match self.iters.get_mut(self.current) {
Some(iter) => {
next = (*iter).next()
},
None => {
panic!("altern.current out of bound for altern.iters ")
},
}
match next {
Some(value) => {
self.current = (self.current + 1) % self.iters.len();
return Some(value)
},
None => {
let _ = self.iters.remove(self.current);
let n = self.iters.len().max(1);
self.current = self.current % n;
}
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::VecAltern;
#[test]
fn vec_altern() {
let vec1 = vec![1, 4, 7, 9];
let vec2 = vec![2, 5];
let vec3 = vec![3, 6, 8];
let iter = VecAltern::new().add_and(vec1.iter()).add_and(vec2.iter()).add_and(vec3.iter());
assert_eq!(iter.collect::<Vec<_>>(), vec![&1,&2,&3,&4,&5,&6,&7,&8, &9]);
}
#[test]
fn empty_vec_altern() {
let vec1 : Vec<u8> = vec![];
let vec2: Vec<u8> = vec![];
let vec3: Vec<u8> = vec![];
let mut iter = VecAltern::new().add_and(vec1.iter()).add_and(vec2.iter()).add_and(vec3.iter());
assert_eq!(iter.next(), None);
}
use crate::altern;
#[test]
fn macro_altern() {
let vec1 = vec![1, 4, 7, 9];
let vec2 = vec![2, 5];
let vec3 = vec![3, 6, 8];
let iter = altern!(vec1.iter(), vec2.iter(), vec3.iter());
assert_eq!(iter.collect::<Vec<_>>(), vec![&1,&2,&3,&4,&5,&6,&7,&8, &9]);
}
}