ark_poly_commit/
optional_rng.rs

1use ark_std::rand::{Error, RngCore};
2use core::num::NonZeroU32;
3
4/// `OptionalRng` is a hack that is necessary because `Option<&mut R>` is not implicitly reborrowed
5/// like `&mut R` is. This causes problems when a variable of type `Option<&mut R>`
6/// is moved (eg, in a loop).
7///
8/// To overcome this, we define the wrapper `OptionalRng` here that can be borrowed
9/// mutably, without fear of being moved.
10pub struct OptionalRng<R>(pub Option<R>);
11
12impl<R: RngCore> RngCore for OptionalRng<R> {
13    #[inline]
14    fn next_u32(&mut self) -> u32 {
15        (&mut self.0)
16            .as_mut()
17            .map(|r| r.next_u32())
18            .expect("Rng was invoked in a non-hiding context")
19    }
20
21    #[inline]
22    fn next_u64(&mut self) -> u64 {
23        (&mut self.0)
24            .as_mut()
25            .map(|r| r.next_u64())
26            .expect("Rng was invoked in a non-hiding context")
27    }
28
29    #[inline]
30    fn fill_bytes(&mut self, dest: &mut [u8]) {
31        (&mut self.0)
32            .as_mut()
33            .map(|r| r.fill_bytes(dest))
34            .expect("Rng was invoked in a non-hiding context")
35    }
36
37    #[inline]
38    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
39        match &mut self.0 {
40            Some(r) => r.try_fill_bytes(dest),
41            None => Err(NonZeroU32::new(Error::CUSTOM_START).unwrap().into()),
42        }
43    }
44}
45
46impl<R: RngCore> From<R> for OptionalRng<R> {
47    fn from(other: R) -> Self {
48        Self(Some(other))
49    }
50}