stdrandom 0.3.0-alpha.1

Generate random numbers using only Rust standard library
Documentation
use super::*;

use std::sync::{Arc, Mutex};
use std::ops::Bound;

#[test]
fn test_gen_range_with_mutable_increasing_closure() {
    let counter = Arc::new(Mutex::new(0u64));
    let counter_clone_for_closure = Arc::clone(&counter);

    let increasing_rng_closure = move || {
        let mut count = counter_clone_for_closure.lock().unwrap();
        *count += 1;
        *count
    };

    let range = 10u64..20u64;
    let returned_value: u64 = gen_range(range.clone(), increasing_rng_closure);

    let start_bound = match range.start_bound() {
        Bound::Included(&val) => val,
        Bound::Excluded(&val) => val + 1,
        Bound::Unbounded => u64::MIN,
    };

    let end_bound_exclusive = match range.end_bound() {
        Bound::Included(&val) => val + 1,
        Bound::Excluded(&val) => val,
        Bound::Unbounded => u64::MAX,
    };

    assert!(
        (start_bound..end_bound_exclusive).contains(&returned_value),
        "Generated value {} is out of expected range {:?}.",
        returned_value,
        range
    );

    let final_counter_value = *counter.lock().unwrap();
    assert_eq!(
        final_counter_value,
        1,
        "Expected counter in closure to be 1 after calling gen_range."
    );

    println!("Test successful.");
    println!("Returned value from gen_range: {}", returned_value);
    println!("Final counter value in closure: {}", final_counter_value);
}

#[test]
fn test_if_closure_is_copy_trait() {
    let value = 0u64; // `u64` is Copy
    let rng_closure = || value + 1; // Does not capture any non-Copy values

    // Checking if the closure is Copy by trying to create multiple instances
    let _rng_closure_clone = rng_closure; // If Copy, this should work without explicit cloning
    let _rng_closure_second = rng_closure; // Should still work if Copy

    let returned_value: u64 = gen_range(0..=50000, rng_closure);
    assert_eq!(
        returned_value,
        1,
        "Expected gen_range to return 1, but got {} instead",
        returned_value
    );

    println!("Test successful. Closure is Copy-compatible.");
}

#[test]
fn test_if_closure_is_copy_trait2() {
    let mut value = 0u64; // `u64` is Copy
    let rng_closure = move || { value +=1; value }; 

    // Checking if the closure is Copy by trying to create multiple instances
    let _rng_closure_clone = rng_closure; // If Copy, this should work without explicit cloning
    let _rng_closure_second = rng_closure; // Should still work if Copy

    let returned_value: u64 = gen_range(0..=50000, rng_closure);
    assert_eq!(
        returned_value,
        1,
        "Expected gen_range to return 1, but got {} instead",
        returned_value
    );

    println!("Test successful. Closure is Copy-compatible.");
}

#[test]
fn test_if_closure_is_copy_trait3() {
    let mut value = 0u64; // `u64` is Copy
    let rng_closure = move || { value +=1; value }; 

    // Checking if the closure is Copy by trying to create multiple instances
    let _rng_closure_clone = rng_closure; // If Copy, this should work without explicit cloning
    let _rng_closure_second = rng_closure; // Should still work if Copy

    let mut mutable = rng_closure;
    assert_eq!( mutable(), 1);
    assert_eq!( mutable(), 2);
    mutable = _rng_closure_clone;
    assert_eq!( mutable(), 1);

    println!("Test successful. Closure is Copy-compatible.");
}

#[test]
fn test_closure_copy_trait_ro() {
    let value = 0u64; // `u64` is Copy
    let rng_closure = || value + 1; // Does NOT modify captured value

    let _clone1 = rng_closure; // If Copy, this works
    let _clone2 = rng_closure; // If Copy, this also works

    assert_eq!(_clone1(), 1);
    assert_eq!(_clone1(), 1);
    assert_eq!(_clone2(), 1); // Should be the same result

    println!("Closure is Copy-compatible.");
}

#[test]
fn test_closure_copy_trait_rw() {
    let mut value = 0u64; // `u64` is Copy
    let rng_closure = move || { value +=1; value }; 

    let mut _clone1 = rng_closure; // If Copy, this works
    let mut _clone2 = rng_closure; // If Copy, this also works

    assert_eq!(_clone1(), 1);
    assert_eq!(_clone1(), 2);
    assert_eq!(_clone2(), 1); // Should be the same result
    assert_eq!(_clone2(), 2); // Should be the same result
    assert_eq!(_clone1(), 3);

    println!("Closure is Copy-compatible.");
}

#[test]
fn test_if_closure_is_copy_compiletime() {
    fn takes_copy<F: Copy>(_: F) {}

    let value = 0u64; // `u64` is Copy
    let rng_closure = || value + 1; // Does not modify captured values

    takes_copy(rng_closure); // If this compiles, closure is Copy

    let _clone1 = rng_closure;
    let _clone2 = rng_closure;

    assert_eq!(_clone1(), 1);
    assert_eq!(_clone2(), 1);
    assert_eq!(rng_closure(), 1);

    println!("Closure is truly Copy-compatible.");
}

#[test]
fn test_if_closure_is_copy_compiletime_rw() {
    fn takes_copy<F: Copy>(_: F) {}

    let mut value = 0u64; // `u64` is Copy
    let rng_closure = move || { value +=1; value }; 

    takes_copy(rng_closure); // If this compiles, closure is Copy

    let mut _clone1 = rng_closure;
    let mut _clone2 = rng_closure;

    assert_eq!(_clone1(), 1);
    assert_eq!(_clone2(), 1);

    println!("Closure is truly Copy-compatible.");
}

#[test]
fn test_if_closure_is_copy_compiletime_retval_check() {
    fn takes_copy<F: Copy + FnMut() -> u64>(closure: F) -> u64 {
        let mut mutable_closure = closure;
        mutable_closure() // Executes the closure and returns its value
    }

    let mut value = 0u64; // `u64` is Copy
    let rng_closure = move || { value +=1; value }; 

    let result1 = takes_copy(rng_closure); // If this compiles, closure is Copy
    let result2 = takes_copy(rng_closure); // If this compiles, closure is Copy

    let mut _clone1 = rng_closure;
    let mut _clone2 = rng_closure;

    assert_eq!(_clone1(), 1);
    assert_eq!(_clone2(), 1);
    assert_eq!(result1, 1, "Expected takes_copy to return 1, but got {}", result1);
    assert_eq!(result2, 1, "Expected takes_copy to return 1, but got {}", result2);

    println!("Closure is truly Copy-compatible.");
}

#[test]
#[allow(non_snake_case)]
fn test_if_closure_is_copy_42_chatGPT() {
    fn takes_copy<F: Copy + FnMut() -> u64>(closure: F) -> (u64, u64) {
        let mut copy1 = closure;
        let mut copy2 = closure; // If closure is Copy, this works
        (copy1(), copy2())
    }

    let mut value = 41u64; // `u64` is Copy
    let rng_closure = move || { value +=1; value }; 

    let (result1, result2) = takes_copy(rng_closure);
    
    assert_eq!(result1, 42, "left value not ok");
    assert_eq!(result2, 42, "right value not ok");
    
    println!("Closure is truly Copy-compatible.");
}