rtools/
random.rs

1use std::ops::Range;
2
3use itertools::Itertools;
4use rand::{
5    distributions::{Alphanumeric, DistString},
6    prelude::SliceRandom,
7    thread_rng, Rng,
8};
9
10pub trait Random<T = Self>: Sized {
11    fn random() -> Self {
12        unimplemented!()
13    }
14
15    fn random_count(_: usize) -> Self {
16        unimplemented!()
17    }
18
19    fn random_in(_: Range<Self>) -> Self {
20        unimplemented!()
21    }
22}
23
24pub trait RandomContainer<T>: Sized {
25    fn random_member(&self) -> &T {
26        unimplemented!()
27    }
28    fn take_random(&mut self) -> T {
29        unimplemented!()
30    }
31}
32
33impl Random for bool {
34    fn random() -> Self {
35        let mut rng = thread_rng();
36        rng.gen_range(0..=1) != 0
37    }
38}
39
40impl Random for char {
41    fn random() -> Self {
42        thread_rng().gen()
43    }
44
45    fn random_in(range: Range<Self>) -> Self {
46        thread_rng().gen_range(range)
47    }
48}
49
50impl Random for String {
51    fn random() -> Self {
52        let mut rng = thread_rng();
53        Alphanumeric.sample_string(&mut rng, 8)
54    }
55}
56
57impl Random for u8 {
58    fn random() -> Self {
59        thread_rng().gen()
60    }
61
62    fn random_in(range: Range<Self>) -> Self {
63        thread_rng().gen_range(range)
64    }
65}
66
67impl Random for i32 {
68    fn random() -> Self {
69        thread_rng().gen_range(-100..100)
70    }
71
72    fn random_in(range: Range<Self>) -> Self {
73        thread_rng().gen_range(range)
74    }
75}
76
77impl Random for u64 {
78    fn random() -> Self {
79        thread_rng().gen_range(0..100)
80    }
81
82    fn random_in(range: Range<Self>) -> Self {
83        thread_rng().gen_range(range)
84    }
85}
86
87impl Random for i64 {
88    fn random() -> Self {
89        thread_rng().gen_range(-100..100)
90    }
91
92    fn random_in(range: Range<Self>) -> Self {
93        thread_rng().gen_range(range)
94    }
95}
96
97impl Random for u32 {
98    fn random() -> Self {
99        thread_rng().gen_range(0..100)
100    }
101
102    fn random_in(range: Range<Self>) -> Self {
103        thread_rng().gen_range(range)
104    }
105}
106
107impl Random for isize {
108    fn random() -> Self {
109        thread_rng().gen_range(0..100)
110    }
111
112    fn random_in(range: Range<Self>) -> Self {
113        thread_rng().gen_range(range)
114    }
115}
116
117impl Random for usize {
118    fn random() -> Self {
119        thread_rng().gen_range(0..100)
120    }
121
122    fn random_in(range: Range<Self>) -> Self {
123        thread_rng().gen_range(range)
124    }
125}
126
127impl Random for f32 {
128    fn random() -> Self {
129        thread_rng().gen_range(0.0..100.0)
130    }
131
132    fn random_in(range: Range<Self>) -> Self {
133        thread_rng().gen_range(range)
134    }
135}
136
137impl Random for f64 {
138    fn random() -> Self {
139        thread_rng().gen_range(0.0..100.0)
140    }
141
142    fn random_in(range: Range<Self>) -> Self {
143        thread_rng().gen_range(range)
144    }
145}
146
147impl<T: Random<T>> Random<Vec<T>> for Vec<T> {
148    fn random() -> Self {
149        (0..usize::random_in(5..10)).map(|_| T::random()).collect_vec()
150    }
151
152    fn random_count(count: usize) -> Self {
153        (0..count).map(|_| T::random()).collect_vec()
154    }
155}
156
157impl<T> RandomContainer<T> for Vec<T> {
158    fn random_member(&self) -> &T {
159        self.choose(&mut thread_rng()).unwrap()
160    }
161
162    fn take_random(&mut self) -> T {
163        self.remove(usize::random_in(0..self.len()))
164    }
165}
166
167#[cfg(test)]
168mod test {
169    use std::ops::Range;
170
171    use itertools::Itertools;
172
173    use crate::{random::RandomContainer, Random};
174
175    fn test_random_type<T: Random + PartialEq>() {
176        let data = (0..10).map(|_| T::random()).collect_vec();
177        let first = data.first().unwrap();
178
179        assert_eq!(data.iter().all(|a| *a == *first), false);
180    }
181
182    #[test]
183    #[should_panic]
184    fn test_random_type_test() {
185        #[derive(PartialEq)]
186        struct NotRandom {
187            a: i32,
188        }
189
190        impl Random for NotRandom {
191            fn random() -> Self {
192                NotRandom { a: 10 }
193            }
194        }
195
196        test_random_type::<NotRandom>()
197    }
198
199    #[test]
200    fn random_test() {
201        test_random_type::<bool>();
202        test_random_type::<char>();
203        test_random_type::<u8>();
204        test_random_type::<u32>();
205        test_random_type::<i32>();
206        test_random_type::<u64>();
207        test_random_type::<i64>();
208        test_random_type::<isize>();
209        test_random_type::<usize>();
210        test_random_type::<f32>();
211        test_random_type::<f64>();
212        test_random_type::<char>();
213        test_random_type::<String>();
214        test_random_type::<Vec<u32>>();
215    }
216
217    #[test]
218    fn random_in_test() {
219        fn test_type<T: Random + Clone + PartialOrd>(range: Range<T>) {
220            for _ in 0..1000 {
221                let ran = T::random_in(range.clone());
222                assert!(range.contains(&ran));
223            }
224        }
225
226        test_type::<char>('a'..'z');
227        test_type::<u8>(5..100);
228        test_type::<u32>(5..100);
229        test_type::<i32>(5..100);
230        test_type::<u64>(5..100);
231        test_type::<i64>(5..100);
232        test_type::<isize>(5..100);
233        test_type::<usize>(5..100);
234        test_type::<f32>(5.0..100.0);
235        test_type::<f64>(5.0..100.0);
236    }
237
238    #[test]
239    fn random_vec_elem() {
240        for _ in 0..100 {
241            let ve = vec![1, 2, 3, 4, 5];
242            let r = ve.random_member();
243            assert!(ve.contains(r));
244        }
245    }
246
247    #[test]
248    fn take_random() {
249        for _ in 0..100 {
250            let mut ve = vec![1, 2, 3, 4, 5, 6, 7, 8];
251            let val = ve.take_random();
252            assert!(!ve.contains(&val));
253        }
254    }
255
256    #[test]
257    fn random_ver_gen() {
258        let random = Vec::<u32>::random();
259        dbg!(&random);
260        let random_count = Vec::<u32>::random_count(10);
261        dbg!(&random_count);
262        assert_eq!(random_count.len(), 10);
263    }
264}