Coverage Report

Created: 2026-10-17 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.10.3/src/lib.rs
Line
Count
Source
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
//! Random-number generators and samplers
11
//!
12
//! # Quick Start
13
//!
14
//! ```
15
//! // rand::random() supports many common types:
16
//! println!("Uniform i8 sample: {}", match rand::random() {
17
//!     0i8 => "zero",
18
//!     i if i > 0 => "positive",
19
//!     _ => "negative",
20
//! });
21
//!
22
//! // Ranged sampling:
23
//! use std::f32::consts::PI;
24
//! println!("Angle: {} radians", rand::random_range(-PI..PI));
25
//! ```
26
//!
27
//! See also [The Book: Quick Start](https://rust-random.github.io/book/quick-start.html).
28
29
#![doc(
30
    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
31
    html_favicon_url = "https://www.rust-lang.org/favicon.ico"
32
)]
33
#![deny(missing_docs)]
34
#![deny(missing_debug_implementations)]
35
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
36
#![no_std]
37
#![cfg_attr(feature = "simd_support", feature(portable_simd))]
38
#![cfg_attr(
39
    all(feature = "simd_support", target_feature = "avx512bw"),
40
    feature(stdarch_x86_avx512)
41
)]
42
#![cfg_attr(docsrs, feature(doc_cfg))]
43
#![allow(
44
    clippy::float_cmp,
45
    clippy::neg_cmp_op_on_partial_ord,
46
    clippy::nonminimal_bool
47
)]
48
#![deny(clippy::undocumented_unsafe_blocks)]
49
50
#[cfg(feature = "alloc")]
51
extern crate alloc;
52
#[cfg(feature = "std")]
53
extern crate std;
54
55
// Re-export rand_core itself
56
pub use rand_core;
57
58
// Re-exports from rand_core
59
pub use rand_core::{CryptoRng, Rng, SeedableRng, TryCryptoRng, TryRng};
60
61
// Public modules
62
pub mod distr;
63
pub mod prelude;
64
mod rng;
65
pub mod rngs;
66
pub mod seq;
67
68
// Public exports
69
#[cfg(feature = "thread_rng")]
70
pub use crate::rngs::thread::rng;
71
72
pub use rng::{Fill, RngExt};
73
74
#[cfg(feature = "thread_rng")]
75
use crate::distr::{Distribution, StandardUniform};
76
77
/// Construct and seed an RNG
78
///
79
/// This method yields a seeded RNG, using [`rng`] ([`ThreadRng`]) if enabled or
80
/// [`SysRng`] otherwise.
81
///
82
/// # Examples
83
///
84
/// ```
85
/// let mut rng: rand::rngs::SmallRng = rand::make_rng();
86
/// # let _ = rand::Rng::next_u32(&mut rng);
87
/// ```
88
///
89
/// # Panics
90
///
91
/// If [`SysRng`] fails to obtain entropy from the OS. This is unlikely
92
/// outside of early boot or unusual system conditions.
93
///
94
/// # Security
95
///
96
/// Refer to [`ThreadRng#Security`].
97
///
98
/// [`SysRng`]: crate::rngs::SysRng
99
/// [`ThreadRng`]: crate::rngs::ThreadRng
100
/// [`ThreadRng#Security`]: crate::rngs::ThreadRng#security
101
#[cfg(feature = "sys_rng")]
102
#[track_caller]
103
0
pub fn make_rng<R: SeedableRng>() -> R {
104
    #[cfg(feature = "thread_rng")]
105
    {
106
0
        R::from_rng(&mut rng())
107
    }
108
109
    #[cfg(not(feature = "thread_rng"))]
110
    {
111
        R::try_from_rng(&mut rngs::SysRng).expect("unexpected failure from SysRng")
112
    }
113
0
}
114
115
/// Adapter to support [`std::io::Read`] over a [`TryRng`]
116
///
117
/// # Examples
118
///
119
/// ```no_run
120
/// use std::{io, io::Read};
121
/// use std::fs::File;
122
/// use rand::{rngs::SysRng, RngReader};
123
///
124
/// io::copy(
125
///     &mut RngReader(SysRng).take(100),
126
///     &mut File::create("/tmp/random.bytes").unwrap()
127
/// ).unwrap();
128
/// ```
129
#[cfg(feature = "std")]
130
pub struct RngReader<R: TryRng>(pub R);
131
132
#[cfg(feature = "std")]
133
impl<R: TryRng> std::io::Read for RngReader<R> {
134
    #[inline]
135
0
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
136
0
        self.0
137
0
            .try_fill_bytes(buf)
138
0
            .map_err(|err| std::io::Error::other(std::format!("RNG error: {err}")))?;
139
0
        Ok(buf.len())
140
0
    }
141
}
142
143
#[cfg(feature = "std")]
144
impl<R: TryRng> std::fmt::Debug for RngReader<R> {
145
0
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146
0
        f.debug_tuple("RngReader").finish()
147
0
    }
148
}
149
150
/// Generate a random value using the thread-local random number generator.
151
///
152
/// This function is shorthand for <code>[rng()].[random()](RngExt::random)</code>:
153
///
154
/// -   See [`ThreadRng`] for documentation of the generator and security
155
/// -   See [`StandardUniform`] for documentation of supported types and distributions
156
///
157
/// # Examples
158
///
159
/// ```
160
/// let x = rand::random::<u8>();
161
/// println!("{}", x);
162
///
163
/// let y = rand::random::<f64>();
164
/// println!("{}", y);
165
///
166
/// if rand::random() { // generates a boolean
167
///     println!("Better lucky than good!");
168
/// }
169
/// ```
170
///
171
/// If you're calling `random()` repeatedly, consider using a local `rng`
172
/// handle to save an initialization-check on each usage:
173
///
174
/// ```
175
/// use rand::RngExt; // provides the `random` method
176
///
177
/// let mut rng = rand::rng(); // a local handle to the generator
178
///
179
/// let mut v = vec![1, 2, 3];
180
///
181
/// for x in v.iter_mut() {
182
///     *x = rng.random();
183
/// }
184
/// ```
185
///
186
/// [`StandardUniform`]: distr::StandardUniform
187
/// [`ThreadRng`]: rngs::ThreadRng
188
#[cfg(feature = "thread_rng")]
189
#[inline]
190
0
pub fn random<T>() -> T
191
0
where
192
0
    StandardUniform: Distribution<T>,
193
{
194
0
    rng().random()
195
0
}
Unexecuted instantiation: rand::random::<[u8; 16]>
Unexecuted instantiation: rand::random::<[u8; 4]>
Unexecuted instantiation: rand::random::<_>
196
197
/// Return an iterator over [`random()`] variates
198
///
199
/// This function is shorthand for
200
/// <code>[rng()].[random_iter](RngExt::random_iter)()</code>.
201
///
202
/// # Example
203
///
204
/// ```
205
/// let v: Vec<i32> = rand::random_iter().take(5).collect();
206
/// println!("{v:?}");
207
/// ```
208
#[cfg(feature = "thread_rng")]
209
#[inline]
210
0
pub fn random_iter<T>() -> distr::Iter<StandardUniform, rngs::ThreadRng, T>
211
0
where
212
0
    StandardUniform: Distribution<T>,
213
{
214
0
    rng().random_iter()
215
0
}
216
217
/// Generate a random value in the given range using the thread-local random number generator.
218
///
219
/// This function is shorthand for
220
/// <code>[rng()].[random_range](RngExt::random_range)(<var>range</var>)</code>.
221
///
222
/// # Example
223
///
224
/// ```
225
/// let y: f32 = rand::random_range(0.0..=1e9);
226
/// println!("{}", y);
227
///
228
/// let words: Vec<&str> = "Mary had a little lamb".split(' ').collect();
229
/// println!("{}", words[rand::random_range(..words.len())]);
230
/// ```
231
/// Note that the second example can also be achieved (without `collect`'ing
232
/// to a `Vec`) using [`seq::IteratorRandom::choose`].
233
#[cfg(feature = "thread_rng")]
234
#[inline]
235
0
pub fn random_range<T, R>(range: R) -> T
236
0
where
237
0
    T: distr::uniform::SampleUniform,
238
0
    R: distr::uniform::SampleRange<T>,
239
{
240
0
    rng().random_range(range)
241
0
}
242
243
/// Return a bool with a probability `p` of being true.
244
///
245
/// This function is shorthand for
246
/// <code>[rng()].[random_bool](RngExt::random_bool)(<var>p</var>)</code>.
247
///
248
/// # Example
249
///
250
/// ```
251
/// println!("{}", rand::random_bool(1.0 / 3.0));
252
/// ```
253
///
254
/// # Panics
255
///
256
/// If `p < 0` or `p > 1`.
257
#[cfg(feature = "thread_rng")]
258
#[inline]
259
#[track_caller]
260
0
pub fn random_bool(p: f64) -> bool {
261
0
    rng().random_bool(p)
262
0
}
263
264
/// Return a bool with a probability of `numerator/denominator` of being
265
/// true.
266
///
267
/// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
268
/// returning true. If `numerator == denominator`, then the returned value
269
/// is guaranteed to be `true`. If `numerator == 0`, then the returned
270
/// value is guaranteed to be `false`.
271
///
272
/// See also the [`Bernoulli`] distribution, which may be faster if
273
/// sampling from the same `numerator` and `denominator` repeatedly.
274
///
275
/// This function is shorthand for
276
/// <code>[rng()].[random_ratio](RngExt::random_ratio)(<var>numerator</var>, <var>denominator</var>)</code>.
277
///
278
/// # Panics
279
///
280
/// If `denominator == 0` or `numerator > denominator`.
281
///
282
/// # Example
283
///
284
/// ```
285
/// println!("{}", rand::random_ratio(2, 3));
286
/// ```
287
///
288
/// [`Bernoulli`]: distr::Bernoulli
289
#[cfg(feature = "thread_rng")]
290
#[inline]
291
#[track_caller]
292
0
pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
293
0
    rng().random_ratio(numerator, denominator)
294
0
}
295
296
/// Fill any type implementing [`Fill`] with random data
297
///
298
/// This function is shorthand for
299
/// <code>[rng()].[fill](RngExt::fill)(<var>dest</var>)</code>.
300
///
301
/// # Example
302
///
303
/// ```
304
/// let mut arr = [0i8; 20];
305
/// rand::fill(&mut arr[..]);
306
/// ```
307
///
308
/// Note that you can instead use [`random()`] to generate an array of random
309
/// data, though this is slower for small elements (smaller than the RNG word
310
/// size).
311
#[cfg(feature = "thread_rng")]
312
#[inline]
313
#[track_caller]
314
0
pub fn fill<T: Fill>(dest: &mut [T]) {
315
0
    Fill::fill_slice(dest, &mut rng())
316
0
}
317
318
#[cfg(test)]
319
mod test {
320
    use super::*;
321
    use core::convert::Infallible;
322
323
    /// Construct a deterministic RNG with the given seed
324
    pub fn rng(seed: u64) -> impl Rng {
325
        // For tests, we want a statistically good, fast, reproducible RNG.
326
        // PCG32 will do fine, and will be easy to embed if we ever need to.
327
        const INC: u64 = 11634580027462260723;
328
        rand_pcg::Pcg32::new(seed, INC)
329
    }
330
331
    /// Construct a generator yielding a constant value
332
    pub fn const_rng(x: u64) -> StepRng {
333
        StepRng(x, 0)
334
    }
335
336
    /// Construct a generator yielding an arithmetic sequence
337
    pub fn step_rng(x: u64, increment: u64) -> StepRng {
338
        StepRng(x, increment)
339
    }
340
341
    #[derive(Clone)]
342
    pub struct StepRng(u64, u64);
343
    impl TryRng for StepRng {
344
        type Error = Infallible;
345
346
        fn try_next_u32(&mut self) -> Result<u32, Infallible> {
347
            self.try_next_u64().map(|x| x as u32)
348
        }
349
350
        fn try_next_u64(&mut self) -> Result<u64, Infallible> {
351
            let res = self.0;
352
            self.0 = self.0.wrapping_add(self.1);
353
            Ok(res)
354
        }
355
356
        fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Infallible> {
357
            rand_core::utils::fill_bytes_via_next_word(dst, || self.try_next_u64())
358
        }
359
    }
360
361
    #[cfg(feature = "std")]
362
    #[test]
363
    fn rng_reader() {
364
        use std::io::Read;
365
366
        let mut rng = StepRng(255, 1);
367
        let mut buf = [0u8; 24];
368
        let expected = [
369
            255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
370
        ];
371
372
        RngReader(&mut rng).read_exact(&mut buf).unwrap();
373
        assert_eq!(&buf, &expected);
374
375
        RngReader(StepRng(255, 1)).read_exact(&mut buf).unwrap();
376
        assert_eq!(&buf, &expected);
377
    }
378
379
    #[test]
380
    #[cfg(feature = "thread_rng")]
381
    fn test_random() {
382
        let _n: u64 = random();
383
        let _f: f32 = random();
384
        #[allow(clippy::type_complexity)]
385
        let _many: (
386
            (),
387
            [(u32, bool); 3],
388
            (u8, i8, u16, i16, u32, i32, u64, i64),
389
            (f32, (f64, (f64,))),
390
        ) = random();
391
    }
392
393
    #[test]
394
    #[cfg(feature = "thread_rng")]
395
    fn test_range() {
396
        let _n: usize = random_range(42..=43);
397
        let _f: f32 = random_range(42.0..43.0);
398
    }
399
}