fray 0.1.2

A type-safe and ergonomic Rust library for working with bitfields.
Documentation
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);
    }
}