musli_tests/models/
generate.rs1#[cfg(feature = "std")]
2use core::hash::Hash;
3use core::ops::Range;
4
5use alloc::ffi::CString;
6use alloc::string::String;
7use alloc::vec::Vec;
8
9use rand::distributions::Distribution;
10use rand::distributions::Standard;
11
12#[cfg(feature = "std")]
13use std::collections::HashMap;
14
15miri! {
16 const STRING_RANGE: Range<usize> = 0..256, 0..16;
17 #[cfg(feature = "std")]
18 const MAP_RANGE: Range<usize> = 10..100, 1..3;
19 const VEC_RANGE: Range<usize> = 10..100, 1..3;
20}
21
22pub trait Generate: Sized {
23 fn generate<R>(rng: &mut R) -> Self
25 where
26 R: rand::Rng;
27
28 fn generate_range<R>(rng: &mut R, _: Range<usize>) -> Self
30 where
31 R: rand::Rng,
32 {
33 Self::generate(rng)
34 }
35}
36
37impl<T> Generate for Vec<T>
38where
39 T: Generate,
40{
41 #[inline]
42 fn generate<R>(rng: &mut R) -> Self
43 where
44 R: rand::Rng,
45 {
46 <Vec<T> as Generate>::generate_range(rng, VEC_RANGE)
47 }
48
49 fn generate_range<R>(rng: &mut R, range: Range<usize>) -> Self
50 where
51 R: rand::Rng,
52 {
53 let cap = rng.gen_range(range);
54 let mut vec = Vec::with_capacity(cap);
55
56 for _ in 0..cap {
57 vec.push(T::generate(rng));
58 }
59
60 vec
61 }
62}
63
64#[cfg(feature = "std")]
65impl<K, V> Generate for HashMap<K, V>
66where
67 K: Eq + Hash,
68 K: Generate,
69 V: Generate,
70{
71 #[inline]
72 fn generate<T>(rng: &mut T) -> Self
73 where
74 T: rand::Rng,
75 {
76 Self::generate_range(rng, MAP_RANGE)
77 }
78
79 fn generate_range<T>(rng: &mut T, range: Range<usize>) -> Self
80 where
81 T: rand::Rng,
82 {
83 let cap = rng.gen_range(range);
84 let mut map = HashMap::with_capacity(cap);
85
86 for _ in 0..cap {
87 map.insert(K::generate(rng), V::generate(rng));
88 }
89
90 map
91 }
92}
93
94impl Generate for String {
95 fn generate<T>(rng: &mut T) -> Self
96 where
97 T: rand::Rng,
98 {
99 let mut string = String::new();
100
101 for _ in 0..rng.gen_range(STRING_RANGE) {
102 string.push(rng.gen());
103 }
104
105 string
106 }
107}
108
109impl Generate for CString {
110 fn generate<T>(rng: &mut T) -> Self
111 where
112 T: rand::Rng,
113 {
114 let mut string = Vec::new();
115
116 for _ in 0..rng.gen_range(STRING_RANGE) {
117 string.push(rng.gen_range(1..=u8::MAX));
118 }
119
120 string.push(0);
121 CString::from_vec_with_nul(string).unwrap()
122 }
123}
124
125impl Generate for () {
126 #[inline]
127 fn generate<T>(_: &mut T) -> Self
128 where
129 T: rand::Rng,
130 {
131 }
132}
133
134macro_rules! tuple {
135 ($($ty:ident),* $(,)?) => {
136 impl<$($ty,)*> Generate for ($($ty,)*) where $($ty: Generate,)* {
137 #[inline]
138 fn generate<T>(rng: &mut T) -> Self where T: rand::Rng {
139 ($(<$ty>::generate(rng),)*)
140 }
141 }
142 }
143}
144
145tuple!(A);
146tuple!(A, B);
147tuple!(A, B, C);
148tuple!(A, B, C, D);
149tuple!(A, B, C, D, E);
150tuple!(A, B, C, D, E, F);
151tuple!(A, B, C, D, E, F, G);
152
153macro_rules! primitive {
154 ($ty:ty) => {
155 impl Generate for $ty
156 where
157 Standard: Distribution<$ty>,
158 {
159 #[inline]
160 fn generate<T>(rng: &mut T) -> Self
161 where
162 T: rand::Rng,
163 {
164 rng.gen()
165 }
166 }
167 };
168}
169
170primitive!(u8);
171primitive!(u16);
172primitive!(u32);
173primitive!(u64);
174primitive!(u128);
175primitive!(i8);
176primitive!(i16);
177primitive!(i32);
178primitive!(i64);
179primitive!(i128);
180primitive!(usize);
181primitive!(isize);
182primitive!(f32);
183primitive!(f64);
184primitive!(char);
185primitive!(bool);