|
1 | | -//! The `Generator` trait and implementation helpers |
| 1 | +//! Support for block generators |
2 | 2 | //! |
3 | | -//! The [`Generator`] trait exists to assist in the implementation of RNGs |
4 | | -//! which generate a block of data in a cache instead of returning generated |
5 | | -//! values directly. |
6 | | -//! |
7 | | -//! Usage of this trait is optional, but provides two advantages: |
8 | | -//! implementations only need to concern themselves with generation of the |
9 | | -//! block, not the various [`RngCore`] methods (especially [`fill_bytes`], where |
10 | | -//! the optimal implementations are not trivial), and this allows |
11 | | -//! `ReseedingRng` (see [`rand`](https://docs.rs/rand) crate) perform periodic |
12 | | -//! reseeding with very low overhead. |
| 3 | +//! The [`BlockRng`] and [`BlockRng64`] types may be used to provide an |
| 4 | +//! implementation of [`RngCore`] over a block [`Generator`]. |
13 | 5 | //! |
14 | 6 | //! # Example |
15 | 7 | //! |
16 | 8 | //! ```no_run |
17 | | -//! use rand_core::{RngCore, SeedableRng}; |
18 | | -//! use rand_core::block::{Generator, BlockRng}; |
| 9 | +//! use rand_core::{Generator, RngCore, SeedableRng}; |
| 10 | +//! use rand_core::block::BlockRng; |
19 | 11 | //! |
20 | 12 | //! struct MyRngCore; |
21 | 13 | //! |
|
45 | 37 | //! [`fill_bytes`]: RngCore::fill_bytes |
46 | 38 |
|
47 | 39 | use crate::le::fill_via_chunks; |
48 | | -use crate::{CryptoRng, RngCore, SeedableRng, TryRngCore}; |
| 40 | +use crate::*; |
49 | 41 | use core::fmt; |
50 | 42 | #[cfg(feature = "serde")] |
51 | 43 | use serde::{Deserialize, Serialize}; |
52 | 44 |
|
53 | | -/// A random generator |
54 | | -pub trait Generator { |
55 | | - /// The result type. |
56 | | - /// |
57 | | - /// This could be a simple word like `u64` or an array like `[u32; 16]`. |
58 | | - type Result; |
59 | | - |
60 | | - /// Generate a new result. |
61 | | - /// |
62 | | - /// Since [`Self::Result`] may be large, the output is passed by reference. |
63 | | - /// Word generators should likely implement this as a shim over another |
64 | | - /// method: |
65 | | - /// ``` |
66 | | - /// pub struct CountingGenerator(u64); |
67 | | - /// impl CountingGenerator { |
68 | | - /// fn next(&mut self) -> u64 { |
69 | | - /// let x = self.0; |
70 | | - /// self.0 = self.0.wrapping_add(1); |
71 | | - /// x |
72 | | - /// } |
73 | | - /// } |
74 | | - /// |
75 | | - /// impl rand_core::block::Generator for CountingGenerator { |
76 | | - /// type Result = u64; |
77 | | - /// |
78 | | - /// #[inline] |
79 | | - /// fn generate(&mut self, result: &mut Self::Result) { |
80 | | - /// *result = self.next(); |
81 | | - /// } |
82 | | - /// } |
83 | | - /// ``` |
84 | | - fn generate(&mut self, result: &mut Self::Result); |
85 | | -} |
86 | | - |
87 | | -/// A cryptographically secure generator |
88 | | -/// |
89 | | -/// This is a marker trait used to indicate that a [`Generator`] implementation |
90 | | -/// is supposed to be cryptographically secure. |
91 | | -/// |
92 | | -/// Mock generators should not implement this trait *except* under a |
93 | | -/// `#[cfg(test)]` attribute to ensure that mock "crypto" generators cannot be |
94 | | -/// used in production. |
95 | | -/// |
96 | | -/// See [`CryptoRng`] docs for more information. |
97 | | -pub trait CryptoGenerator: Generator {} |
98 | | - |
99 | 45 | /// A wrapper type implementing [`RngCore`] for some type implementing |
100 | 46 | /// [`Generator`] with `u32` array buffer; i.e. this can be used to implement |
101 | 47 | /// a full RNG from just a `generate` function. |
@@ -247,9 +193,7 @@ impl<const N: usize, R: Generator<Result = [u32; N]>> RngCore for BlockRng<R> { |
247 | 193 | } |
248 | 194 | } |
249 | 195 |
|
250 | | -impl<const N: usize, R: Generator<Result = [u32; N]> + SeedableRng> SeedableRng |
251 | | - for BlockRng<R> |
252 | | -{ |
| 196 | +impl<const N: usize, R: Generator<Result = [u32; N]> + SeedableRng> SeedableRng for BlockRng<R> { |
253 | 197 | type Seed = R::Seed; |
254 | 198 |
|
255 | 199 | #[inline(always)] |
@@ -306,9 +250,7 @@ pub struct BlockRng64<R: Generator + ?Sized> { |
306 | 250 | } |
307 | 251 |
|
308 | 252 | // Custom Debug implementation that does not expose the contents of `results`. |
309 | | -impl<const N: usize, R: Generator<Result = [u64; N]> + fmt::Debug> fmt::Debug |
310 | | - for BlockRng64<R> |
311 | | -{ |
| 253 | +impl<const N: usize, R: Generator<Result = [u64; N]> + fmt::Debug> fmt::Debug for BlockRng64<R> { |
312 | 254 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
313 | 255 | fmt.debug_struct("BlockRng64") |
314 | 256 | .field("core", &self.core) |
@@ -414,9 +356,7 @@ impl<const N: usize, R: Generator<Result = [u64; N]>> RngCore for BlockRng64<R> |
414 | 356 | } |
415 | 357 | } |
416 | 358 |
|
417 | | -impl<const N: usize, R: Generator<Result = [u64; N]> + SeedableRng> SeedableRng |
418 | | - for BlockRng64<R> |
419 | | -{ |
| 359 | +impl<const N: usize, R: Generator<Result = [u64; N]> + SeedableRng> SeedableRng for BlockRng64<R> { |
420 | 360 | type Seed = R::Seed; |
421 | 361 |
|
422 | 362 | #[inline(always)] |
|
0 commit comments