use core::ops::RangeBounds;
pub struct Substitute<T, I: Iterator<Item = T>, I2: Iterator<Item = T>, R: RangeBounds<usize>> {
ite: I,
replace_with: I2,
range: R,
index: usize,
}
impl<T, I, I2, R> Substitute<T, I, I2, R>
where
I: Iterator<Item = T>,
I2: Iterator<Item = T>,
R: RangeBounds<usize>,
{
pub fn new(ite: I, replace_with: I2, range: R) -> Self {
Substitute {
ite,
replace_with,
range,
index: 0,
}
}
}
impl<T, I, I2, R> Iterator for Substitute<T, I, I2, R>
where
I: Iterator<Item = T>,
I2: Iterator<Item = T>,
R: RangeBounds<usize>,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let in_range = self.range.contains(&self.index);
let mut item = self.ite.next();
if in_range && let Some(replace_item) = self.replace_with.next() {
item = Some(replace_item);
}
self.index += 1;
item
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::vec;
use std::vec::Vec;
#[test]
fn substitute_at_start() {
let sub = Substitute::new(0..10, 10..15, 0..5);
let expected = vec![10i32, 11, 12, 13, 14, 5, 6, 7, 8, 9];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
#[test]
fn substitute_at_end() {
let sub = Substitute::new(0..10, 10..15, 5..10);
let expected = vec![0, 1, 2, 3, 4, 10, 11, 12, 13, 14];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
#[test]
fn substitute_in_middle() {
let sub = Substitute::new(0..10, 10..15, 2..7);
let expected = vec![0, 1, 10, 11, 12, 13, 14, 7, 8, 9];
assert_eq!(sub.collect::<Vec<i32>>(), expected)
}
#[test]
fn substitute_range_exceeds_ite() {
let sub = Substitute::new(0..10, 10..15, 9..14);
let expected = vec![0i32, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
#[test]
fn substitute_range_smaller_than_replacement() {
let sub = Substitute::new(0..10, 10..15, 9..10);
let expected = vec![0i32, 1, 2, 3, 4, 5, 6, 7, 8, 10];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
#[test]
fn substitute_range_bigger_than_replacement() {
let sub = Substitute::new(0..10, 10..11, 2..7);
let expected = vec![0i32, 1, 10i32, 3, 4, 5, 6, 7, 8, 9];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
#[test]
fn substitute_range_smaller_than_replacement_exceeds_ite() {
let sub = Substitute::new(0..10, 10..12, 9..15);
let expected = vec![0i32, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
#[test]
fn substitute_range_bigger_than_replacement_exceeds_ite() {
let sub = Substitute::new(0..10, 10..11, 10..15);
let expected = vec![0i32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
#[test]
fn substitute_range_starts_after_ite() {
let sub = Substitute::new(0..10, 10..15, 11..15);
let expected = vec![0i32, 1, 2, 3, 4, 5, 6, 7, 8, 9];
assert_eq!(sub.collect::<Vec<i32>>(), expected);
}
}