aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob McWhirter <[email protected]>2021-08-27 16:10:01 -0400
committerBob McWhirter <[email protected]>2021-08-27 16:10:01 -0400
commitd525f519405745c9133e112da40b954302c128c3 (patch)
tree8b77818d408cf13d4cbab4bffa99a37297c85367
parente56c6166dcac9132cde1769e5ef8d60e03963329 (diff)
Add a convenience next(range) to Rng.
-rw-r--r--embassy-stm32/src/rng.rs20
-rw-r--r--embassy-traits/src/rng.rs8
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
131pub(crate) mod sealed { 151pub(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;
4pub trait Rng { 4pub 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}