Skip to main content

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