@@ -793,6 +793,60 @@ pub trait SeedableRng: Sized {
793
793
}
794
794
}
795
795
796
+
797
+ /// Seeding mechanism for PRNGs, providing a `new` function.
798
+ /// This is the recommended way to create (pseudo) random number generators,
799
+ /// unless a deterministic seed is desired (in which case
800
+ /// `SeedableRng::from_seed` should be used).
801
+ ///
802
+ /// Note: this trait is automatically implemented for any PRNG implementing
803
+ /// `SeedableRng` and is not intended to be implemented by users.
804
+ ///
805
+ /// ## Example
806
+ ///
807
+ /// ```
808
+ /// use rand::{StdRng, Rng, NewSeeded};
809
+ ///
810
+ /// let mut rng = StdRng::new().unwrap();
811
+ /// println!("Random die roll: {}", rng.gen_range(1, 7));
812
+ /// ```
813
+ #[ cfg( feature="std" ) ]
814
+ pub trait NewSeeded : SeedableRng {
815
+ /// Creates a new instance, automatically seeded with fresh entropy.
816
+ ///
817
+ /// Normally this will use `OsRng`, but if that fails `JitterRng` will be
818
+ /// used instead. Both should be suitable for cryptography. It is possible
819
+ /// that both entropy sources will fail though unlikely.
820
+ fn new ( ) -> Result < Self , Error > ;
821
+ }
822
+
823
+ #[ cfg( feature="std" ) ]
824
+ impl < R : SeedableRng > NewSeeded for R {
825
+ fn new ( ) -> Result < Self , Error > {
826
+ // Note: error handling would be easier with try/catch blocks
827
+ fn new_os < T : SeedableRng > ( ) -> Result < T , Error > {
828
+ let mut r = OsRng :: new ( ) ?;
829
+ T :: from_rng ( & mut r)
830
+ }
831
+
832
+ fn new_jitter < T : SeedableRng > ( ) -> Result < T , Error > {
833
+ let mut r = JitterRng :: new ( ) ?;
834
+ T :: from_rng ( & mut r)
835
+ }
836
+
837
+ new_os ( ) . or_else ( |e1| {
838
+ new_jitter ( ) . map_err ( |_e2| {
839
+ // TODO: log
840
+ // TODO: can we somehow return both error sources?
841
+ Error :: with_cause (
842
+ ErrorKind :: Unavailable ,
843
+ "seeding a new RNG failed: both OS and Jitter entropy sources failed" ,
844
+ e1)
845
+ } )
846
+ } )
847
+ }
848
+ }
849
+
796
850
/// A wrapper for generating floating point numbers uniformly in the
797
851
/// open interval `(0,1)` (not including either endpoint).
798
852
///
@@ -836,34 +890,6 @@ pub struct Closed01<F>(pub F);
836
890
#[ derive( Clone , Debug ) ]
837
891
pub struct StdRng ( IsaacWordRng ) ;
838
892
839
- impl StdRng {
840
- /// Create a randomly seeded instance of `StdRng`.
841
- ///
842
- /// This is a very expensive operation as it has to read
843
- /// randomness from the operating system and use this in an
844
- /// expensive seeding operation. If one is only generating a small
845
- /// number of random numbers, or doesn't need the utmost speed for
846
- /// generating each number, `thread_rng` and/or `random` may be more
847
- /// appropriate.
848
- ///
849
- /// Reading the randomness from the OS may fail, and any error is
850
- /// propagated via the `io::Result` return value.
851
- #[ cfg( feature="std" ) ]
852
- pub fn new ( ) -> Result < StdRng , Error > {
853
- match OsRng :: new ( ) {
854
- Ok ( mut r) => Ok ( StdRng ( r. gen ( ) ) ) ,
855
- Err ( e1) => {
856
- match JitterRng :: new ( ) {
857
- Ok ( mut r) => Ok ( StdRng ( r. gen ( ) ) ) ,
858
- Err ( _) => {
859
- Err ( e1)
860
- }
861
- }
862
- }
863
- }
864
- }
865
- }
866
-
867
893
impl Rng for StdRng {
868
894
fn next_u32 ( & mut self ) -> u32 {
869
895
self . 0 . next_u32 ( )
@@ -904,7 +930,7 @@ impl SeedableRng for StdRng {
904
930
/// This will seed the generator with randomness from thread_rng.
905
931
#[ cfg( feature="std" ) ]
906
932
pub fn weak_rng ( ) -> XorShiftRng {
907
- thread_rng ( ) . gen ( )
933
+ XorShiftRng :: new ( ) . unwrap ( )
908
934
}
909
935
910
936
/// Controls how the thread-local RNG is reseeded.
0 commit comments