1919/// Re-export the particular version of the `rand` crate whose types appear in the API.
2020pub use rand;
2121
22+ use lazy_static:: lazy_static;
2223use rand:: Rng ;
24+ use std:: sync:: RwLock ;
25+
26+ /// Possible factory functions for producing [`Generator`] instances.
27+ pub enum Factory {
28+ ThreadRng ,
29+ OsRng ,
30+ User ( fn ( ) -> Box < dyn Generator > ) ,
31+ }
32+
33+ lazy_static ! {
34+ /// Global factory that produces [`Generator`] instances.
35+ static ref RNG_FACTORY : RwLock <fn ( ) -> Box <dyn Generator >> = RwLock :: new( thread_rng_factory) ;
36+ }
2337
2438/// Trait that encapsulates the required traits that a generator instance
2539/// must implement.
@@ -28,9 +42,32 @@ pub trait Generator: rand::RngCore + rand::CryptoRng {}
2842// Blanket implementation.
2943impl < T > Generator for T where T : rand:: RngCore + rand:: CryptoRng { }
3044
45+ /// Factory function that produces [`rand::rngs::ThreadRng`] instances.
46+ fn thread_rng_factory ( ) -> Box < dyn Generator > {
47+ // Available if `rand` has feature `std` enabled.
48+ Box :: new ( rand:: thread_rng ( ) )
49+ }
50+
51+ /// Factory function that produces [`rand::rngs::OsRng`] instances.
52+ fn os_rng_factory ( ) -> Box < dyn Generator > {
53+ // Available if `rand` has feature `getrandom` enabled.
54+ Box :: new ( rand:: rngs:: OsRng )
55+ }
56+
57+ /// Set the global factory that produces [`Generator`] instances.
58+ pub fn set_factory ( factory : Factory ) {
59+ let mut global = RNG_FACTORY . write ( ) . unwrap ( ) ; // safe: lock
60+ * global = match factory {
61+ Factory :: ThreadRng => thread_rng_factory,
62+ Factory :: OsRng => os_rng_factory,
63+ Factory :: User ( f) => f,
64+ } ;
65+ }
66+
3167/// Return a random number generator suitable for cryptographic operation.
3268pub fn rng ( ) -> Box < dyn Generator > {
33- Box :: new ( rand:: thread_rng ( ) )
69+ let factory = RNG_FACTORY . read ( ) . unwrap ( ) ; // safe: lock
70+ factory ( )
3471}
3572
3673/// Return a vector of the given `size` filled with random bytes.
0 commit comments