Skip to content

Commit c25b5d4

Browse files
authored
Merge pull request #1187 from vks/cryptorngcore
Add `CryptoRngCore` to support `CryptoRng` trait objects
2 parents da917e6 + a4fa077 commit c25b5d4

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

rand_chacha/src/chacha.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,4 +623,15 @@ mod test {
623623
rng.set_word_pos(0);
624624
assert_eq!(rng.get_word_pos(), 0);
625625
}
626+
627+
#[test]
628+
fn test_trait_objects() {
629+
use rand_core::CryptoRngCore;
630+
631+
let rng = &mut ChaChaRng::from_seed(Default::default()) as &mut dyn CryptoRngCore;
632+
let r1 = rng.next_u64();
633+
let rng: &mut dyn RngCore = rng.as_rngcore();
634+
let r2 = rng.next_u64();
635+
assert_ne!(r1, r2);
636+
}
626637
}

rand_core/src/lib.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,35 @@ pub trait RngCore {
208208
/// [`BlockRngCore`]: block::BlockRngCore
209209
pub trait CryptoRng {}
210210

211+
/// An extension trait that is automatically implemented for any type
212+
/// implementing [`RngCore`] and [`CryptoRng`].
213+
///
214+
/// It may be used as a trait object, and supports upcasting to [`RngCore`] via
215+
/// the [`CryptoRngCore::as_rngcore`] method.
216+
///
217+
/// # Example
218+
///
219+
/// ```
220+
/// use rand_core::CryptoRngCore;
221+
///
222+
/// #[allow(unused)]
223+
/// fn make_token(rng: &mut dyn CryptoRngCore) -> [u8; 32] {
224+
/// let mut buf = [0u8; 32];
225+
/// rng.fill_bytes(&mut buf);
226+
/// buf
227+
/// }
228+
/// ```
229+
pub trait CryptoRngCore: RngCore {
230+
/// Upcast to an [`RngCore`] trait object.
231+
fn as_rngcore(&mut self) -> &mut dyn RngCore;
232+
}
233+
234+
impl<T: CryptoRng + RngCore> CryptoRngCore for T {
235+
fn as_rngcore(&mut self) -> &mut dyn RngCore {
236+
self
237+
}
238+
}
239+
211240
/// A random number generator that can be explicitly seeded.
212241
///
213242
/// This trait encapsulates the low-level functionality common to all
@@ -448,10 +477,10 @@ impl std::io::Read for dyn RngCore {
448477
}
449478
}
450479

451-
// Implement `CryptoRng` for references to an `CryptoRng`.
480+
// Implement `CryptoRng` for references to a `CryptoRng`.
452481
impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}
453482

454-
// Implement `CryptoRng` for boxed references to an `CryptoRng`.
483+
// Implement `CryptoRng` for boxed references to a `CryptoRng`.
455484
#[cfg(feature = "alloc")]
456485
impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}
457486

0 commit comments

Comments
 (0)