Skip to main content

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}