rayon-join 1.12.0

Simple macro to call join from rayon with more than 2 arguments.
Documentation
use std::sync::{Arc, Mutex};

use rayon_join::join;

#[test]
fn two_closures_execute() {
    let log = Arc::new(Mutex::new(Vec::new()));
    let log1 = log.clone();
    let log2 = log.clone();

    join!(
        || {
            log1.lock().unwrap().push(1);
        },
        || {
            log2.lock().unwrap().push(2);
        }
    );

    let mut v = log.lock().unwrap().clone();
    v.sort();
    assert_eq!(v, vec![1, 2]);
}

#[test]
fn two_closures_return_values() {
    let (a, b) = join!(|| 1 + 1, || 2 + 2);
    assert_eq!(a, 2);
    assert_eq!(b, 4);
}

#[test]
fn three_closures_execute() {
    let log = Arc::new(Mutex::new(Vec::new()));
    let log1 = log.clone();
    let log2 = log.clone();
    let log3 = log.clone();

    join!(
        || {
            log1.lock().unwrap().push(1);
        },
        || {
            log2.lock().unwrap().push(2);
        },
        || {
            log3.lock().unwrap().push(3);
        }
    );

    let mut v = log.lock().unwrap().clone();
    v.sort();
    assert_eq!(v, vec![1, 2, 3]);
}

#[test]
fn three_closures_return_nested_tuple() {
    let (a, (b, c)) = join!(|| 10, || 20, || 30);
    assert_eq!(a, 10);
    assert_eq!(b, 20);
    assert_eq!(c, 30);
}

#[test]
fn five_closures_execute() {
    let l0 = Arc::new(Mutex::new(Vec::new()));
    let l1 = Arc::new(Mutex::new(Vec::new()));
    let l2 = Arc::new(Mutex::new(Vec::new()));
    let l3 = Arc::new(Mutex::new(Vec::new()));
    let l4 = Arc::new(Mutex::new(Vec::new()));

    let c0 = l0.clone();
    let c1 = l1.clone();
    let c2 = l2.clone();
    let c3 = l3.clone();
    let c4 = l4.clone();

    join!(
        || {
            c0.lock().unwrap().push(0);
        },
        || {
            c1.lock().unwrap().push(1);
        },
        || {
            c2.lock().unwrap().push(2);
        },
        || {
            c3.lock().unwrap().push(3);
        },
        || {
            c4.lock().unwrap().push(4);
        }
    );

    assert_eq!(*l0.lock().unwrap(), vec![0]);
    assert_eq!(*l1.lock().unwrap(), vec![1]);
    assert_eq!(*l2.lock().unwrap(), vec![2]);
    assert_eq!(*l3.lock().unwrap(), vec![3]);
    assert_eq!(*l4.lock().unwrap(), vec![4]);
}

#[test]
fn named_functions_execute() {
    fn a() -> i32 {
        1
    }
    fn b() -> i32 {
        2
    }
    fn c() -> i32 {
        3
    }

    let (ra, (rb, rc)) = join!(a, b, c);
    assert_eq!(ra, 1);
    assert_eq!(rb, 2);
    assert_eq!(rc, 3);
}

#[test]
fn closures_with_arguments() {
    fn add(x: i32, y: i32) -> i32 {
        x + y
    }

    let (a, (b, c)) = join!(|| add(1, 2), || add(3, 4), || add(5, 6));
    assert_eq!(a, 3);
    assert_eq!(b, 7);
    assert_eq!(c, 11);
}

#[test]
fn two_named_functions_return_values() {
    fn square(x: i32) -> i32 {
        x * x
    }

    let (a, b) = join!(|| square(3), || square(4));
    assert_eq!(a, 9);
    assert_eq!(b, 16);
}

#[test]
fn all_closures_run_exactly_once() {
    let counter = Arc::new(Mutex::new(0u32));

    let c1 = counter.clone();
    let c2 = counter.clone();
    let c3 = counter.clone();
    let c4 = counter.clone();

    join!(
        || {
            *c1.lock().unwrap() += 1;
        },
        || {
            *c2.lock().unwrap() += 1;
        },
        || {
            *c3.lock().unwrap() += 1;
        },
        || {
            *c4.lock().unwrap() += 1;
        }
    );

    assert_eq!(*counter.lock().unwrap(), 4);
}

#[test]
fn deep_recursion_eight_closures() {
    let log = Arc::new(Mutex::new(Vec::new()));

    let l0 = log.clone();
    let l1 = log.clone();
    let l2 = log.clone();
    let l3 = log.clone();
    let l4 = log.clone();
    let l5 = log.clone();
    let l6 = log.clone();
    let l7 = log.clone();

    join!(
        || {
            l0.lock().unwrap().push(0);
        },
        || {
            l1.lock().unwrap().push(1);
        },
        || {
            l2.lock().unwrap().push(2);
        },
        || {
            l3.lock().unwrap().push(3);
        },
        || {
            l4.lock().unwrap().push(4);
        },
        || {
            l5.lock().unwrap().push(5);
        },
        || {
            l6.lock().unwrap().push(6);
        },
        || {
            l7.lock().unwrap().push(7);
        }
    );

    let mut v = log.lock().unwrap().clone();
    v.sort();
    assert_eq!(v, vec![0, 1, 2, 3, 4, 5, 6, 7]);
}

#[test]
fn mixed_closure_and_function() {
    fn triple(x: i32) -> i32 {
        x * 3
    }

    let (a, (b, c)) = join!(|| 5, || triple(4), || 10);
    assert_eq!(a, 5);
    assert_eq!(b, 12);
    assert_eq!(c, 10);
}