From 2de5bea7e4187e5f1ae74a902cab3816e151b5dd Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Wed, 13 Jan 2021 09:31:15 +0000 Subject: [PATCH 1/2] Add an implementation of `rand_core::RngCore` for `Gen` behind an optional (disabled by default) feature flag - `rand_core_0_6`. Structure the features flags to allow backwards-compatible additions of new `RngCore` implementations if `rand_core` were to cut a new release with breaking changes (either 0.7 or 1.x). --- .github/workflows/ci.yml | 2 ++ Cargo.toml | 2 ++ README.md | 9 +++++---- src/arbitrary.rs | 2 ++ src/arbitrary/rand_rng_impl.rs | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 src/arbitrary/rand_rng_impl.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b41f2bc..c755b3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,8 @@ jobs: - run: cargo test --verbose - run: cargo build --verbose --manifest-path quickcheck_macros/Cargo.toml - run: cargo test --verbose --manifest-path quickcheck_macros/Cargo.toml + # Make sure that the crate compiles if all features flags are switched on at the same time. + - run: cargo check --all-features --verbose rustfmt: name: rustfmt diff --git a/Cargo.toml b/Cargo.toml index 75083f4..d2470c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ members = ["quickcheck_macros"] default = ["regex", "use_logging"] use_logging = ["log", "env_logger"] regex = ["env_logger/regex"] +use_rand_core_0_6 = ["rand_core_0_6"] [lib] name = "quickcheck" @@ -28,3 +29,4 @@ name = "quickcheck" env_logger = { version = "0.8.2", default-features = false, optional = true } log = { version = "0.4", optional = true } rand = { version = "0.8", default-features = false, features = ["getrandom", "small_rng"] } +rand_core_0_6 = { package = "rand_core", version = "0.6", default-features = false, optional = true } diff --git a/README.md b/README.md index 2546a63..065ade5 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ Crate features: `RUST_LOG`. - `"regex"`: (Enabled by default.) Enables the use of regexes with `env_logger`. +- `"rand_core_0_6"`: (Disabled by default.) Provides an implementation of + `rand_core::RngCore` for `quickcheck::Gen`. ### Minimum Rust version policy @@ -140,10 +142,9 @@ version of Rust. In general, this crate will be conservative with respect to the minimum supported version of Rust. -With all of that said, currently, `rand` is a public dependency of -`quickcheck`. Therefore, the MSRV policy above only applies when it is more -aggressive than `rand`'s MSRV policy. Otherwise, `quickcheck` will defer to -`rand`'s MSRV policy. +If you are opting-in to use the `rand_core_X_X` feature flags, the MSRV policy +above only applies when it is more aggressive than `rand`'s MSRV policy. +Otherwise, `quickcheck` will defer to `rand`'s MSRV policy. ### Compatibility diff --git a/src/arbitrary.rs b/src/arbitrary.rs index 13b5b65..f46a5d2 100644 --- a/src/arbitrary.rs +++ b/src/arbitrary.rs @@ -24,6 +24,8 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use rand::seq::SliceRandom; use rand::{self, Rng, SeedableRng}; +mod rand_rng_impl; + /// Gen represents a PRNG. /// /// It is the source of randomness from which QuickCheck will generate diff --git a/src/arbitrary/rand_rng_impl.rs b/src/arbitrary/rand_rng_impl.rs new file mode 100644 index 0000000..4a97088 --- /dev/null +++ b/src/arbitrary/rand_rng_impl.rs @@ -0,0 +1,32 @@ +//! Implement the `RngCore` trait from `rand_core` for `quickcheck::Gen`. +//! This allows `quickcheck` to interoperate with other crates that rely on `rand_core`/`rand` as +//! their interface for sources of randomness. +//! +//! The `RngCore` implementations are gated behind opt-in feature flags that are explicitly tied to a +//! pinned version of `rand_core`. +//! If a new version of `rand_core` is released, `quickcheck` can add a new `use_rand_core_X_X` +//! feature flag to enable interoperability without compromising its API stability guarantees. + +#[cfg(feature = "use_rand_core_0_6")] +mod rand_core_0_6 { + use crate::Gen; + use rand::Error; + + impl rand_core_0_6::RngCore for Gen { + fn next_u32(&mut self) -> u32 { + self.rng.next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.rng.next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.rng.fill_bytes(dest) + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + self.rng.try_fill_bytes(dest) + } + } +} From bd38176e791daf12d604e87f1c00dfb925628ac4 Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Wed, 13 Jan 2021 09:48:54 +0000 Subject: [PATCH 2/2] Clarify documentation. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 065ade5..dd49ca7 100644 --- a/README.md +++ b/README.md @@ -125,8 +125,8 @@ Crate features: `RUST_LOG`. - `"regex"`: (Enabled by default.) Enables the use of regexes with `env_logger`. -- `"rand_core_0_6"`: (Disabled by default.) Provides an implementation of - `rand_core::RngCore` for `quickcheck::Gen`. +- `"use_rand_core_0_6"`: (Disabled by default.) Provides an implementation of + `rand_core::RngCore` for `quickcheck::Gen` using version `0.6` of `rand_core`. ### Minimum Rust version policy