emit_rand/lib.rs
1/*!
2An implementation of `emit::Rng` using a specific version of the `rand` library.
3
4`emit` itself has a `rand` feature and provides exactly the same `RandRng`, but only on select platforms. You can use `emit_rand` to always configure `emit` using `rand` if you're also using it elsewhere in your application, and want to guarantee only a specific version will end up in your dependency tree.
5
6## Getting started
7
8Add `emit` and `emit_rand` to your Cargo.toml:
9
10```toml
11[dependencies.emit]
12version = "1"
13# Disable default features of `emit` to avoid pulling in a possibly different version of `rand`
14default-features = false
15features = ["std", "implicit_rt"]
16
17[dependencies.emit_rand]
18version = "0.9"
19```
20
21Configure `emit` to use the `RandRng` type from this library during setup:
22
23```rust
24fn main() {
25 let rt = emit::setup()
26 .with_rng(emit_rand::rng())
27 // Other configuration goes here
28 .init();
29
30 // Your app code goes here
31
32 rt.blocking_flush(std::time::Duration::from_secs(5));
33}
34```
35
36## Versioning and compatibility
37
38`emit_rand` version `x.y.z` is compatible with `rand` version `x.y.*`.
39*/
40
41#![cfg_attr(not(test), no_std)]
42
43use emit_core::{rng::Rng, runtime::InternalRng};
44use rand::{Rng as _, RngExt as _};
45
46/**
47Create a new source of randomness based on [`RandRng`].
48*/
49pub const fn rng() -> RandRng {
50 RandRng::new()
51}
52
53/**
54An [`Rng`] based on the [`rand`] library.
55*/
56#[derive(Default, Debug, Clone, Copy)]
57pub struct RandRng {}
58
59impl RandRng {
60 /**
61 Create a new source of randomness.
62 */
63 pub const fn new() -> Self {
64 RandRng {}
65 }
66}
67
68impl Rng for RandRng {
69 fn fill<A: AsMut<[u8]>>(&self, mut arr: A) -> Option<A> {
70 rand::rng().fill_bytes(arr.as_mut());
71
72 Some(arr)
73 }
74
75 fn gen_u64(&self) -> Option<u64> {
76 Some(rand::rng().random())
77 }
78
79 fn gen_u128(&self) -> Option<u128> {
80 Some(rand::rng().random())
81 }
82}
83
84impl InternalRng for RandRng {}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn gen() {
92 assert_ne!(RandRng::new().gen_u128(), RandRng::new().gen_u128());
93 assert_ne!(RandRng::new().gen_u64(), RandRng::new().gen_u64());
94 assert_ne!(RandRng::new().fill([0; 32]), RandRng::new().fill([0; 32]));
95 }
96}