Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature-gated implementation of rand_core::RngCore for quickcheck::Gen #271

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 }
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ Crate features:
`RUST_LOG`.
- `"regex"`: (Enabled by default.) Enables the use of regexes with
`env_logger`.
- `"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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions src/arbitrary/rand_rng_impl.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
}