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}