orx-concurrent-iter 3.3.0

A thread-safe and ergonomic concurrent iterator trait and efficient lock-free implementations.
Documentation
use orx_concurrent_iter::*;
use std::ops::Range;
use test_case::test_matrix;

#[derive(Clone, Debug)]
struct VecAndRange(Vec<String>, Range<usize>);

impl VecAndRange {
    fn new(n: usize) -> VecAndRange {
        let vec: Vec<_> = (0..n).map(|x| x.to_string()).collect();
        let range = match n % 4 {
            0 => 0..n,
            1 => 0..(n / 2),
            2 => core::cmp::min(n.saturating_sub(1), 3)..n,
            _ => {
                let a = core::cmp::min(n.saturating_sub(1), 3);
                let b = core::cmp::min(a + 10, n);
                a..b
            }
        };
        Self(vec, range)
    }
}

#[test_matrix(
    [0, 1, 2, 3, 71, 72, 73, 74],
    [true, false],
    [true, false]
)]
fn concurrent_drainable_vec(n: usize, use_all: bool, as_seq: bool) {
    let vec_and_range = VecAndRange::new(n);
    let VecAndRange(mut vec, range) = vec_and_range;
    let m = match use_all {
        true => range.len(),
        false => range.len() / 2,
    };

    let mut vec2 = vec.clone();
    let mut drained = vec![];
    {
        let mut draining = vec2.drain(range.clone());
        for _ in 0..m {
            drained.push(draining.next().unwrap());
        }
    }
    let expected = (vec2, drained);

    let mut drained = vec![];
    {
        match as_seq {
            true => {
                let mut draining = vec.con_drain(range).into_seq_iter();
                for _ in 0..m {
                    drained.push(draining.next().unwrap());
                }
            }
            false => {
                let draining = vec.con_drain(range);
                for _ in 0..m {
                    drained.push(draining.next().unwrap());
                }
            }
        }
    }
    let result = (vec, drained);
    assert_eq!(result, expected);
}