1#![doc = include_str!("../README.md")]
2
3use std::{
4 collections::{HashMap, HashSet},
5 hash::Hash,
6 mem::{self, MaybeUninit},
7 num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping},
8};
9
10#[doc(hidden)]
11pub use rand as __rand;
12
13pub use enum_derived_macro::Rand;
15
16pub trait Rand {
18 fn rand() -> Self;
19}
20
21impl<K: Rand + Hash + Eq, V: Rand> Rand for HashMap<K, V> {
22 fn rand() -> Self {
23 let mut map = HashMap::new();
24 let size = (rand::random::<usize>() % 15) + 1;
25 for _ in 0..size {
26 let k = K::rand();
27 let v = V::rand();
28 let _ = map.insert(k, v);
29 }
30 map
31 }
32}
33
34impl<K: Rand + Hash + Eq> Rand for HashSet<K> {
35 fn rand() -> Self {
36 let mut set = HashSet::new();
37 let size = (rand::random::<usize>() % 15) + 1;
38 for _ in 0..size {
39 let k = K::rand();
40 let _ = set.insert(k);
41 }
42 set
43 }
44}
45
46impl<T: Rand> Rand for Option<T> {
47 fn rand() -> Self {
48 if bool::rand() {
49 Some(T::rand())
50 } else {
51 None
52 }
53 }
54}
55
56impl<T: Rand> Rand for Wrapping<T> {
57 fn rand() -> Self {
58 Wrapping(T::rand())
59 }
60}
61
62impl<T: Rand> Rand for Vec<T> {
63 fn rand() -> Self {
64 let size = (rand::random::<usize>() % 63) + 1;
65 let mut out = Vec::with_capacity(size);
66
67 for _ in 0..size {
68 out.push(T::rand());
69 }
70
71 debug_assert!(out.len() == size);
72 out
73 }
74}
75
76impl Rand for String {
77 fn rand() -> Self {
78 let size = (rand::random::<usize>() % 63) + 1;
79 let mut out = Vec::with_capacity(size);
80
81 for _ in 0..size {
82 out.push(char::rand());
83 }
84
85 debug_assert!(out.len() == size);
86 String::from_iter(out.iter())
87 }
88}
89
90impl<T: Rand, const N: usize> Rand for [T; N] {
91 fn rand() -> Self {
92 let mut buff: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
93
94 for elem in &mut buff {
95 *elem = MaybeUninit::new(T::rand());
96 }
97
98 unsafe { mem::transmute_copy::<_, _>(&buff) }
99 }
100}
101
102macro_rules! impl_rand {
103 ($type:ty) => {
104 impl Rand for $type {
105 fn rand() -> Self {
106 ::rand::random()
107 }
108 }
109 };
110}
111
112impl_rand!(bool);
113impl_rand!(char);
114impl_rand!(f32);
115impl_rand!(f64);
116impl_rand!(i8);
117impl_rand!(i16);
118impl_rand!(i32);
119impl_rand!(i64);
120impl_rand!(i128);
121impl_rand!(isize);
122impl_rand!(u8);
123impl_rand!(u16);
124impl_rand!(u32);
125impl_rand!(u64);
126impl_rand!(u128);
127impl_rand!(());
128impl_rand!(usize);
129impl_rand!(NonZeroU8);
130impl_rand!(NonZeroU16);
131impl_rand!(NonZeroU32);
132impl_rand!(NonZeroU64);
133impl_rand!(NonZeroU128);
134impl_rand!(NonZeroUsize);
135
136macro_rules! impl_tuple_rand {
137 ($($tyvar:ident),* ) => {
139 impl< $( $tyvar ),* >
141 Rand
142 for ( $( $tyvar ),* , )
143 where $( $tyvar: Rand ),*
144 {
145 #[inline]
146 fn rand() -> ( $( $tyvar ),* , ) {
147 (
148 $(
151 <$tyvar as Rand>::rand()
152 ),*
153 ,
154 )
155 }
156 }
157 }
158}
159
160impl_tuple_rand! {A}
161impl_tuple_rand! {A, B}
162impl_tuple_rand! {A, B, C}
163impl_tuple_rand! {A, B, C, D}
164impl_tuple_rand! {A, B, C, D, E}
165impl_tuple_rand! {A, B, C, D, E, F}
166impl_tuple_rand! {A, B, C, D, E, F, G}
167impl_tuple_rand! {A, B, C, D, E, F, G, H}
168impl_tuple_rand! {A, B, C, D, E, F, G, H, I}
169impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J}
170impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K}
171impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L}
172impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M}
173impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N}
174impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O}
175impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P}
176impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q}
177impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R}
178impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S}
179impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T}
180impl_tuple_rand! {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U}