19
19
/// Re-export the particular version of the `rand` crate whose types appear in the API.
20
20
pub use rand;
21
21
22
+ use lazy_static:: lazy_static;
22
23
use 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
+ }
23
37
24
38
/// Trait that encapsulates the required traits that a generator instance
25
39
/// must implement.
@@ -28,9 +42,32 @@ pub trait Generator: rand::RngCore + rand::CryptoRng {}
28
42
// Blanket implementation.
29
43
impl < T > Generator for T where T : rand:: RngCore + rand:: CryptoRng { }
30
44
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
+
31
67
/// Return a random number generator suitable for cryptographic operation.
32
68
pub fn rng ( ) -> Box < dyn Generator > {
33
- Box :: new ( rand:: thread_rng ( ) )
69
+ let factory = RNG_FACTORY . read ( ) . unwrap ( ) ; // safe: lock
70
+ factory ( )
34
71
}
35
72
36
73
/// Return a vector of the given `size` filled with random bytes.
0 commit comments