ruint/support/
proptest.rs

1//! Support for the [`proptest`](https://crates.io/crates/proptest) crate.
2
3#![cfg(feature = "proptest")]
4#![cfg_attr(docsrs, doc(cfg(feature = "proptest")))]
5
6use crate::{Bits, Uint};
7use proptest::{arbitrary::Mapped, prelude::*};
8
9impl<const BITS: usize, const LIMBS: usize> Arbitrary for Uint<BITS, LIMBS> {
10    // FEATURE: Would be nice to have a value range as parameter
11    // and/or a choice between uniform and 'exponential' distribution.
12    type Parameters = ();
13    type Strategy = Mapped<[u64; LIMBS], Self>;
14
15    #[inline]
16    fn arbitrary() -> Self::Strategy {
17        Self::arbitrary_with(())
18    }
19
20    fn arbitrary_with((): Self::Parameters) -> Self::Strategy {
21        any::<[u64; LIMBS]>().prop_map(Self::from_limbs_unmasked)
22    }
23}
24
25impl<const BITS: usize, const LIMBS: usize> Arbitrary for Bits<BITS, LIMBS> {
26    type Parameters = <Uint<BITS, LIMBS> as Arbitrary>::Parameters;
27    type Strategy = Mapped<Uint<BITS, LIMBS>, Self>;
28
29    fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
30        Uint::<BITS, LIMBS>::arbitrary_with(args).prop_map(Self::from)
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37    use crate::{const_for, nlimbs};
38    use proptest::proptest;
39
40    #[test]
41    fn test_arbitrary() {
42        const_for!(BITS in SIZES {
43            const LIMBS: usize = nlimbs(BITS);
44            proptest!(|(n: Uint::<BITS, LIMBS>)| {
45                let _ = n;
46            });
47        });
48    }
49}