Skip to main content

windjammer_runtime/
random.rs

1//! Random number generation
2//!
3//! Windjammer's `std::random` module maps to these functions.
4
5use rand::Rng;
6
7/// Generate random integer in range [min, max)
8pub fn int_range(min: i64, max: i64) -> i64 {
9    rand::thread_rng().gen_range(min..max)
10}
11
12/// Generate random float in range [0.0, 1.0)
13pub fn float() -> f64 {
14    rand::thread_rng().gen()
15}
16
17/// Generate random float in range [min, max)
18pub fn float_range(min: f64, max: f64) -> f64 {
19    rand::thread_rng().gen_range(min..max)
20}
21
22/// Generate random boolean
23pub fn bool() -> bool {
24    rand::thread_rng().gen()
25}
26
27/// Choose random element from slice
28pub fn choice<T: Clone>(items: &[T]) -> Option<T> {
29    use rand::seq::SliceRandom;
30    items.choose(&mut rand::thread_rng()).cloned()
31}
32
33/// Shuffle a vector
34pub fn shuffle<T>(items: &mut [T]) {
35    use rand::seq::SliceRandom;
36    items.shuffle(&mut rand::thread_rng());
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn test_int_range() {
45        for _ in 0..100 {
46            let n = int_range(0, 10);
47            assert!((0..10).contains(&n));
48        }
49    }
50
51    #[test]
52    fn test_float() {
53        for _ in 0..100 {
54            let f = float();
55            assert!((0.0..1.0).contains(&f));
56        }
57    }
58
59    #[test]
60    fn test_bool() {
61        let mut true_count = 0;
62        for _ in 0..100 {
63            if bool() {
64                true_count += 1;
65            }
66        }
67        // Should be roughly 50/50
68        assert!(true_count > 20 && true_count < 80);
69    }
70
71    #[test]
72    fn test_choice() {
73        let items = vec![1, 2, 3, 4, 5];
74        for _ in 0..10 {
75            let chosen = choice(&items);
76            assert!(chosen.is_some());
77            assert!(items.contains(&chosen.unwrap()));
78        }
79    }
80}