|
1 | | -//! # Little-Endian utilities |
| 1 | +//! Utilties to aid trait implementations |
| 2 | +//! |
| 3 | +//! ## Portability |
2 | 4 | //! |
3 | 5 | //! For cross-platform reproducibility, Little-Endian order (least-significant |
4 | 6 | //! part first) has been chosen as the standard for inter-type conversion. |
5 | | -//! For example, ``next_u64_via_u32`] takes `u32` |
6 | | -//! values `x, y`, then outputs `(y << 32) | x`. |
| 7 | +//! For example, [`next_u64_via_u32`] generates two `u32` values `x, y`, |
| 8 | +//! then outputs `(y << 32) | x`. |
7 | 9 | //! |
8 | 10 | //! Byte-swapping (like the std `to_le` functions) is only needed to convert |
9 | 11 | //! to/from byte sequences, and since its purpose is reproducibility, |
10 | 12 | //! non-reproducible sources (e.g. `OsRng`) need not bother with it. |
11 | 13 | //! |
12 | | -//! ### Implementing [`RngCore`] |
| 14 | +//! ## Implementing [`RngCore`] |
13 | 15 | //! |
14 | 16 | //! Usually an implementation of [`RngCore`] will implement one of the three |
15 | 17 | //! methods over its internal source. The following helpers are provided for |
|
27 | 29 | //! **`fn fill_bytes`:** |
28 | 30 | //! - <code>[fill_bytes_via_next_word][](self, dest)</code> |
29 | 31 | //! |
30 | | -//! ### Implementing [`SeedableRng`] |
| 32 | +//! ## Implementing [`SeedableRng`] |
31 | 33 | //! |
32 | 34 | //! In many cases, [`SeedableRng::Seed`] must be converted to `[u32; _]` or |
33 | 35 | //! `[u64; _]`. [`read_words`] may be used for this. |
| 36 | +//! |
| 37 | +//! ## Example |
| 38 | +//! |
| 39 | +//! We demonstrate a simple "step RNG": |
| 40 | +//! ``` |
| 41 | +//! use rand_core::{RngCore, SeedableRng, utils}; |
| 42 | +//! |
| 43 | +//! pub struct Step32Rng { |
| 44 | +//! state: u32 |
| 45 | +//! } |
| 46 | +//! |
| 47 | +//! impl SeedableRng for Step32Rng { |
| 48 | +//! type Seed = [u8; 4]; |
| 49 | +//! |
| 50 | +//! #[inline] |
| 51 | +//! fn from_seed(seed: Self::Seed) -> Self { |
| 52 | +//! // Always use little-endian byte order to ensure portable results |
| 53 | +//! let state = u32::from_le_bytes(seed); |
| 54 | +//! Self { state } |
| 55 | +//! } |
| 56 | +//! } |
| 57 | +//! |
| 58 | +//! impl RngCore for Step32Rng { |
| 59 | +//! #[inline] |
| 60 | +//! fn next_u32(&mut self) -> u32 { |
| 61 | +//! let val = self.state; |
| 62 | +//! self.state = val + 1; |
| 63 | +//! val |
| 64 | +//! } |
| 65 | +//! |
| 66 | +//! #[inline] |
| 67 | +//! fn next_u64(&mut self) -> u64 { |
| 68 | +//! utils::next_u64_via_u32(self) |
| 69 | +//! } |
| 70 | +//! |
| 71 | +//! #[inline] |
| 72 | +//! fn fill_bytes(&mut self, dst: &mut [u8]) { |
| 73 | +//! utils::fill_bytes_via_next_word(dst, || self.next_u32()); |
| 74 | +//! } |
| 75 | +//! } |
| 76 | +//! |
| 77 | +//! # let mut rng = Step32Rng::seed_from_u64(42); |
| 78 | +//! # assert_eq!(rng.next_u32(), 0x7ba1_8fa4); |
| 79 | +//! # assert_eq!(rng.next_u64(), 0x7ba1_8fa6_7ba1_8fa5); |
| 80 | +//! # let mut buf = [0u8; 5]; |
| 81 | +//! # rng.fill_bytes(&mut buf); |
| 82 | +//! # assert_eq!(buf, [0xa7, 0x8f, 0xa1, 0x7b, 0xa8]); |
| 83 | +//! ``` |
34 | 84 |
|
35 | 85 | use crate::RngCore; |
36 | 86 | #[allow(unused)] |
|
0 commit comments