Coverage Report

Created: 2025-06-22 07:07

/rust/registry/src/index.crates.io-6f17d22bba15001f/rand-0.9.1/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2018 Developers of the Rand project.
2
// Copyright 2013-2017 The Rust Project Developers.
3
//
4
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7
// option. This file may not be copied, modified, or distributed
8
// except according to those terms.
9
10
//! Utilities for random number generation
11
//!
12
//! Rand provides utilities to generate random numbers, to convert them to
13
//! useful types and distributions, and some randomness-related algorithms.
14
//!
15
//! # Quick Start
16
//!
17
//! ```
18
//! // The prelude import enables methods we use below, specifically
19
//! // Rng::random, Rng::sample, SliceRandom::shuffle and IndexedRandom::choose.
20
//! use rand::prelude::*;
21
//!
22
//! // Get an RNG:
23
//! let mut rng = rand::rng();
24
//!
25
//! // Try printing a random unicode code point (probably a bad idea)!
26
//! println!("char: '{}'", rng.random::<char>());
27
//! // Try printing a random alphanumeric value instead!
28
//! println!("alpha: '{}'", rng.sample(rand::distr::Alphanumeric) as char);
29
//!
30
//! // Generate and shuffle a sequence:
31
//! let mut nums: Vec<i32> = (1..100).collect();
32
//! nums.shuffle(&mut rng);
33
//! // And take a random pick (yes, we didn't need to shuffle first!):
34
//! let _ = nums.choose(&mut rng);
35
//! ```
36
//!
37
//! # The Book
38
//!
39
//! For the user guide and further documentation, please read
40
//! [The Rust Rand Book](https://rust-random.github.io/book).
41
42
#![doc(
43
    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
44
    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
45
    html_root_url = "https://rust-random.github.io/rand/"
46
)]
47
#![deny(missing_docs)]
48
#![deny(missing_debug_implementations)]
49
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
50
#![no_std]
51
#![cfg_attr(feature = "simd_support", feature(portable_simd))]
52
#![cfg_attr(
53
    all(feature = "simd_support", target_feature = "avx512bw"),
54
    feature(stdarch_x86_avx512)
55
)]
56
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
57
#![allow(
58
    clippy::float_cmp,
59
    clippy::neg_cmp_op_on_partial_ord,
60
    clippy::nonminimal_bool
61
)]
62
#![deny(clippy::undocumented_unsafe_blocks)]
63
64
#[cfg(feature = "alloc")]
65
extern crate alloc;
66
#[cfg(feature = "std")]
67
extern crate std;
68
69
#[allow(unused)]
70
macro_rules! trace { ($($x:tt)*) => (
71
    #[cfg(feature = "log")] {
72
        log::trace!($($x)*)
73
    }
74
) }
75
#[allow(unused)]
76
macro_rules! debug { ($($x:tt)*) => (
77
    #[cfg(feature = "log")] {
78
        log::debug!($($x)*)
79
    }
80
) }
81
#[allow(unused)]
82
macro_rules! info { ($($x:tt)*) => (
83
    #[cfg(feature = "log")] {
84
        log::info!($($x)*)
85
    }
86
) }
87
#[allow(unused)]
88
macro_rules! warn { ($($x:tt)*) => (
89
    #[cfg(feature = "log")] {
90
        log::warn!($($x)*)
91
    }
92
) }
93
#[allow(unused)]
94
macro_rules! error { ($($x:tt)*) => (
95
    #[cfg(feature = "log")] {
96
        log::error!($($x)*)
97
    }
98
) }
99
100
// Re-export rand_core itself
101
pub use rand_core;
102
103
// Re-exports from rand_core
104
pub use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore};
105
106
// Public modules
107
pub mod distr;
108
pub mod prelude;
109
mod rng;
110
pub mod rngs;
111
pub mod seq;
112
113
// Public exports
114
#[cfg(feature = "thread_rng")]
115
pub use crate::rngs::thread::rng;
116
117
/// Access the thread-local generator
118
///
119
/// Use [`rand::rng()`](rng()) instead.
120
#[cfg(feature = "thread_rng")]
121
#[deprecated(since = "0.9.0", note = "Renamed to `rng`")]
122
#[inline]
123
0
pub fn thread_rng() -> crate::rngs::ThreadRng {
124
0
    rng()
125
0
}
126
127
pub use rng::{Fill, Rng};
128
129
#[cfg(feature = "thread_rng")]
130
use crate::distr::{Distribution, StandardUniform};
131
132
/// Generate a random value using the thread-local random number generator.
133
///
134
/// This function is shorthand for <code>[rng()].[random()](Rng::random)</code>:
135
///
136
/// -   See [`ThreadRng`] for documentation of the generator and security
137
/// -   See [`StandardUniform`] for documentation of supported types and distributions
138
///
139
/// # Examples
140
///
141
/// ```
142
/// let x = rand::random::<u8>();
143
/// println!("{}", x);
144
///
145
/// let y = rand::random::<f64>();
146
/// println!("{}", y);
147
///
148
/// if rand::random() { // generates a boolean
149
///     println!("Better lucky than good!");
150
/// }
151
/// ```
152
///
153
/// If you're calling `random()` repeatedly, consider using a local `rng`
154
/// handle to save an initialization-check on each usage:
155
///
156
/// ```
157
/// use rand::Rng; // provides the `random` method
158
///
159
/// let mut rng = rand::rng(); // a local handle to the generator
160
///
161
/// let mut v = vec![1, 2, 3];
162
///
163
/// for x in v.iter_mut() {
164
///     *x = rng.random();
165
/// }
166
/// ```
167
///
168
/// [`StandardUniform`]: distr::StandardUniform
169
/// [`ThreadRng`]: rngs::ThreadRng
170
#[cfg(feature = "thread_rng")]
171
#[inline]
172
0
pub fn random<T>() -> T
173
0
where
174
0
    StandardUniform: Distribution<T>,
175
0
{
176
0
    rng().random()
177
0
}
Unexecuted instantiation: rand::random::<[u8; 5]>
Unexecuted instantiation: rand::random::<_>
178
179
/// Return an iterator over [`random()`] variates
180
///
181
/// This function is shorthand for
182
/// <code>[rng()].[random_iter](Rng::random_iter)()</code>.
183
///
184
/// # Example
185
///
186
/// ```
187
/// let v: Vec<i32> = rand::random_iter().take(5).collect();
188
/// println!("{v:?}");
189
/// ```
190
#[cfg(feature = "thread_rng")]
191
#[inline]
192
0
pub fn random_iter<T>() -> distr::Iter<StandardUniform, rngs::ThreadRng, T>
193
0
where
194
0
    StandardUniform: Distribution<T>,
195
0
{
196
0
    rng().random_iter()
197
0
}
198
199
/// Generate a random value in the given range using the thread-local random number generator.
200
///
201
/// This function is shorthand for
202
/// <code>[rng()].[random_range](Rng::random_range)(<var>range</var>)</code>.
203
///
204
/// # Example
205
///
206
/// ```
207
/// let y: f32 = rand::random_range(0.0..=1e9);
208
/// println!("{}", y);
209
///
210
/// let words: Vec<&str> = "Mary had a little lamb".split(' ').collect();
211
/// println!("{}", words[rand::random_range(..words.len())]);
212
/// ```
213
/// Note that the first example can also be achieved (without `collect`'ing
214
/// to a `Vec`) using [`seq::IteratorRandom::choose`].
215
#[cfg(feature = "thread_rng")]
216
#[inline]
217
0
pub fn random_range<T, R>(range: R) -> T
218
0
where
219
0
    T: distr::uniform::SampleUniform,
220
0
    R: distr::uniform::SampleRange<T>,
221
0
{
222
0
    rng().random_range(range)
223
0
}
224
225
/// Return a bool with a probability `p` of being true.
226
///
227
/// This function is shorthand for
228
/// <code>[rng()].[random_bool](Rng::random_bool)(<var>p</var>)</code>.
229
///
230
/// # Example
231
///
232
/// ```
233
/// println!("{}", rand::random_bool(1.0 / 3.0));
234
/// ```
235
///
236
/// # Panics
237
///
238
/// If `p < 0` or `p > 1`.
239
#[cfg(feature = "thread_rng")]
240
#[inline]
241
#[track_caller]
242
0
pub fn random_bool(p: f64) -> bool {
243
0
    rng().random_bool(p)
244
0
}
245
246
/// Return a bool with a probability of `numerator/denominator` of being
247
/// true.
248
///
249
/// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
250
/// returning true. If `numerator == denominator`, then the returned value
251
/// is guaranteed to be `true`. If `numerator == 0`, then the returned
252
/// value is guaranteed to be `false`.
253
///
254
/// See also the [`Bernoulli`] distribution, which may be faster if
255
/// sampling from the same `numerator` and `denominator` repeatedly.
256
///
257
/// This function is shorthand for
258
/// <code>[rng()].[random_ratio](Rng::random_ratio)(<var>numerator</var>, <var>denominator</var>)</code>.
259
///
260
/// # Panics
261
///
262
/// If `denominator == 0` or `numerator > denominator`.
263
///
264
/// # Example
265
///
266
/// ```
267
/// println!("{}", rand::random_ratio(2, 3));
268
/// ```
269
///
270
/// [`Bernoulli`]: distr::Bernoulli
271
#[cfg(feature = "thread_rng")]
272
#[inline]
273
#[track_caller]
274
0
pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
275
0
    rng().random_ratio(numerator, denominator)
276
0
}
277
278
/// Fill any type implementing [`Fill`] with random data
279
///
280
/// This function is shorthand for
281
/// <code>[rng()].[fill](Rng::fill)(<var>dest</var>)</code>.
282
///
283
/// # Example
284
///
285
/// ```
286
/// let mut arr = [0i8; 20];
287
/// rand::fill(&mut arr[..]);
288
/// ```
289
///
290
/// Note that you can instead use [`random()`] to generate an array of random
291
/// data, though this is slower for small elements (smaller than the RNG word
292
/// size).
293
#[cfg(feature = "thread_rng")]
294
#[inline]
295
#[track_caller]
296
0
pub fn fill<T: Fill + ?Sized>(dest: &mut T) {
297
0
    dest.fill(&mut rng())
298
0
}
299
300
#[cfg(test)]
301
mod test {
302
    use super::*;
303
304
    /// Construct a deterministic RNG with the given seed
305
    pub fn rng(seed: u64) -> impl RngCore {
306
        // For tests, we want a statistically good, fast, reproducible RNG.
307
        // PCG32 will do fine, and will be easy to embed if we ever need to.
308
        const INC: u64 = 11634580027462260723;
309
        rand_pcg::Pcg32::new(seed, INC)
310
    }
311
312
    #[test]
313
    #[cfg(feature = "thread_rng")]
314
    fn test_random() {
315
        let _n: u64 = random();
316
        let _f: f32 = random();
317
        #[allow(clippy::type_complexity)]
318
        let _many: (
319
            (),
320
            [(u32, bool); 3],
321
            (u8, i8, u16, i16, u32, i32, u64, i64),
322
            (f32, (f64, (f64,))),
323
        ) = random();
324
    }
325
326
    #[test]
327
    #[cfg(feature = "thread_rng")]
328
    fn test_range() {
329
        let _n: usize = random_range(42..=43);
330
        let _f: f32 = random_range(42.0..43.0);
331
    }
332
}