rand06_compat/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4/// Compatibility extension trait for RNGs implementing `0.9` `RngCore` trait.
5pub trait Rand0_6CompatExt {
6    /// Wraps `self` in a compatibility wrapper that implements `0.6` traits.
7    fn compat(self) -> Rand0_6CompatWrapper<Self>
8    where
9        Self: Sized,
10    {
11        Rand0_6CompatWrapper(self)
12    }
13
14    /// Wraps `self` in a compatibility wrapper that implements `0.6` traits.
15    ///
16    /// Same as [`Rand0_6CompatExt::compat`] but instead of taking ownership it borrows.
17    fn compat_by_ref(&mut self) -> Rand0_6CompatWrapper<&mut Self>
18    where
19        Self: Sized,
20    {
21        Rand0_6CompatWrapper(self)
22    }
23}
24
25impl<T> Rand0_6CompatExt for T where T: rand_core::TryRngCore + ?Sized {}
26
27/// Rand 0.6 compatibility wrapper.
28pub struct Rand0_6CompatWrapper<R: ?Sized>(R);
29
30impl<R> Rand0_6CompatWrapper<R> {
31    /// Creates a new compatibility wrapper.
32    pub fn new(inner: R) -> Self {
33        Self(inner)
34    }
35
36    /// Returns the inner value.
37    pub fn into_inner(self) -> R {
38        self.0
39    }
40}
41
42#[cfg(not(feature = "std"))]
43impl<R> rand_core_06::RngCore for Rand0_6CompatWrapper<R>
44where
45    R: rand_core::TryRngCore + ?Sized,
46{
47    fn next_u32(&mut self) -> u32 {
48        self.0.try_next_u32().unwrap()
49    }
50
51    fn next_u64(&mut self) -> u64 {
52        self.0.try_next_u64().unwrap()
53    }
54
55    fn fill_bytes(&mut self, dest: &mut [u8]) {
56        self.0.try_fill_bytes(dest).unwrap()
57    }
58
59    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
60        self.0
61            .try_fill_bytes(dest)
62            .map_err(|_| rand_core_06::Error::from(core::num::NonZeroU32::new(1).unwrap()))
63    }
64}
65
66#[cfg(feature = "std")]
67impl<R> rand_core_06::RngCore for Rand0_6CompatWrapper<R>
68where
69    R: rand_core::TryRngCore + ?Sized,
70    R::Error: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
71{
72    fn next_u32(&mut self) -> u32 {
73        self.0.try_next_u32().unwrap()
74    }
75
76    fn next_u64(&mut self) -> u64 {
77        self.0.try_next_u64().unwrap()
78    }
79
80    fn fill_bytes(&mut self, dest: &mut [u8]) {
81        self.0.try_fill_bytes(dest).unwrap()
82    }
83
84    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
85        self.0
86            .try_fill_bytes(dest)
87            .map_err(rand_core_06::Error::new)
88    }
89}
90
91impl<R> rand_core_06::CryptoRng for Rand0_6CompatWrapper<R> where R: rand_core::CryptoRng + ?Sized {}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    use rand_core::OsRng;
98    use rand_core_06::RngCore as RngCore06;
99
100    fn foo<R>(rng: &mut R)
101    where
102        R: RngCore06,
103    {
104        let _: u32 = rng.next_u32();
105    }
106
107    #[test]
108    fn test_compat_os_rng() {
109        foo(&mut OsRng.compat());
110    }
111
112    #[test]
113    fn test_compat_thread_rng() {
114        let mut rng = rand::rng();
115        foo(&mut (rng.compat_by_ref()));
116        foo(&mut rng.compat());
117    }
118}