diff options
| author | Bob McWhirter <[email protected]> | 2021-08-27 16:10:01 -0400 |
|---|---|---|
| committer | Bob McWhirter <[email protected]> | 2021-08-27 16:10:01 -0400 |
| commit | d525f519405745c9133e112da40b954302c128c3 (patch) | |
| tree | 8b77818d408cf13d4cbab4bffa99a37297c85367 | |
| parent | e56c6166dcac9132cde1769e5ef8d60e03963329 (diff) | |
Add a convenience next(range) to Rng.
| -rw-r--r-- | embassy-stm32/src/rng.rs | 20 | ||||
| -rw-r--r-- | embassy-traits/src/rng.rs | 8 |
2 files changed, 28 insertions, 0 deletions
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 77e408d3d..e94c813de 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs | |||
| @@ -126,6 +126,26 @@ impl<T: Instance> traits::rng::Rng for Random<T> { | |||
| 126 | Ok(()) | 126 | Ok(()) |
| 127 | } | 127 | } |
| 128 | } | 128 | } |
| 129 | |||
| 130 | #[rustfmt::skip] | ||
| 131 | type NextFuture<'a> where Self: 'a = impl Future<Output=Result<u32, Self::Error>> + 'a; | ||
| 132 | |||
| 133 | fn next<'a>(&'a mut self, range: u32) -> Self::NextFuture<'a> { | ||
| 134 | async move { | ||
| 135 | let t = (-(range as i32) % (range as i32)) as u32; | ||
| 136 | loop { | ||
| 137 | let mut buf = [0; 4]; | ||
| 138 | traits::rng::Rng::fill_bytes(self, &mut buf).await?; | ||
| 139 | let x = u32::from_le_bytes(buf); | ||
| 140 | let m = x as u64 * range as u64; | ||
| 141 | let l = m as u32; | ||
| 142 | if l < t { | ||
| 143 | continue; | ||
| 144 | } | ||
| 145 | return Ok((m >> 32) as u32); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | } | ||
| 129 | } | 149 | } |
| 130 | 150 | ||
| 131 | pub(crate) mod sealed { | 151 | pub(crate) mod sealed { |
diff --git a/embassy-traits/src/rng.rs b/embassy-traits/src/rng.rs index ddc4c20e0..320d9afc2 100644 --- a/embassy-traits/src/rng.rs +++ b/embassy-traits/src/rng.rs | |||
| @@ -4,6 +4,7 @@ use core::future::Future; | |||
| 4 | pub trait Rng { | 4 | pub trait Rng { |
| 5 | type Error; | 5 | type Error; |
| 6 | 6 | ||
| 7 | #[rustfmt::skip] | ||
| 7 | type RngFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a | 8 | type RngFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a |
| 8 | where | 9 | where |
| 9 | Self: 'a; | 10 | Self: 'a; |
| @@ -14,4 +15,11 @@ pub trait Rng { | |||
| 14 | /// filling the buffer. Upon completion, the buffer will be completely | 15 | /// filling the buffer. Upon completion, the buffer will be completely |
| 15 | /// filled or an error will have been reported. | 16 | /// filled or an error will have been reported. |
| 16 | fn fill_bytes<'a>(&'a mut self, dest: &'a mut [u8]) -> Self::RngFuture<'a>; | 17 | fn fill_bytes<'a>(&'a mut self, dest: &'a mut [u8]) -> Self::RngFuture<'a>; |
| 18 | |||
| 19 | #[rustfmt::skip] | ||
| 20 | type NextFuture<'a>: Future<Output = Result<u32, Self::Error>> + 'a | ||
| 21 | where | ||
| 22 | Self: 'a; | ||
| 23 | |||
| 24 | fn next<'a>(&'a mut self, range: u32) -> Self::NextFuture<'a>; | ||
| 17 | } | 25 | } |
