Skip to content

Commit

Permalink
Make getrandom a non-pub dep; rename feature to os_rng (#1537)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhardy authored Nov 26, 2024
1 parent c1f865f commit 0ff946c
Show file tree
Hide file tree
Showing 19 changed files with 95 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
RUSTDOCFLAGS: --cfg doc_cfg
# --all builds all crates, but with default features for other crates (okay in this case)
run: |
cargo doc --all --features nightly,serde,getrandom,small_rng
cargo doc --all --all-features --no-deps
cp utils/redirect.html target/doc/index.html
rm target/doc/.lock
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ jobs:
- name: Test rand
run: |
cargo test --target ${{ matrix.target }} --lib --tests --no-default-features
cargo build --target ${{ matrix.target }} --no-default-features --features alloc,getrandom,small_rng,unbiased
cargo test --target ${{ matrix.target }} --lib --tests --no-default-features --features=alloc,getrandom,small_rng
cargo build --target ${{ matrix.target }} --no-default-features --features alloc,os_rng,small_rng,unbiased
cargo test --target ${{ matrix.target }} --lib --tests --no-default-features --features=alloc,os_rng,small_rng
cargo test --target ${{ matrix.target }} --examples
- name: Test rand (all stable features)
run: |
Expand All @@ -100,7 +100,7 @@ jobs:
run: |
cargo test --target ${{ matrix.target }} --manifest-path rand_core/Cargo.toml
cargo test --target ${{ matrix.target }} --manifest-path rand_core/Cargo.toml --no-default-features
cargo test --target ${{ matrix.target }} --manifest-path rand_core/Cargo.toml --no-default-features --features=alloc,getrandom
cargo test --target ${{ matrix.target }} --manifest-path rand_core/Cargo.toml --no-default-features --features=alloc,os_rng
- name: Test rand_distr
run: |
cargo test --target ${{ matrix.target }} --manifest-path rand_distr/Cargo.toml --features=serde
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
- Remove impl of `Distribution<Option<T>>` for `Standard` (#1526)
- Remove `SmallRng::from_thread_rng` (#1532)
- Remove first parameter (`rng`) of `ReseedingRng::new` (#1533)
- Rename feature `getrandom` to `os_rng`

## [0.9.0-alpha.1] - 2024-03-18
- Add the `Slice::num_choices` method to the Slice distribution (#1402)
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ features = ["small_rng", "serde"]

[features]
# Meta-features:
default = ["std", "std_rng", "getrandom", "small_rng"]
default = ["std", "std_rng", "os_rng", "small_rng"]
nightly = [] # some additions requiring nightly Rust
serde = ["dep:serde", "rand_core/serde"]

Expand All @@ -39,8 +39,8 @@ std = ["rand_core/std", "rand_chacha?/std", "alloc"]
# Option: "alloc" enables support for Vec and Box when not using "std"
alloc = ["rand_core/alloc"]

# Option: use getrandom package for seeding
getrandom = ["rand_core/getrandom"]
# Option: enable OsRng
os_rng = ["rand_core/os_rng"]

# Option (requires nightly Rust): experimental SIMD support
simd_support = ["zerocopy/simd-nightly"]
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Rand is a set of crates supporting (pseudo-)random generators:
- With fast implementations of both [strong](https://rust-random.github.io/book/guide-rngs.html#cryptographically-secure-pseudo-random-number-generators-csprngs) and
[small](https://rust-random.github.io/book/guide-rngs.html#basic-pseudo-random-number-generators-prngs) generators: [`rand::rngs`](https://docs.rs/rand/latest/rand/rngs/index.html), and more RNGs: [`rand_chacha`](https://docs.rs/rand_chacha), [`rand_xoshiro`](https://docs.rs/rand_xoshiro/), [`rand_pcg`](https://docs.rs/rand_pcg/), [rngs repo](https://github.com/rust-random/rngs/)
- [`rand::rng`](https://docs.rs/rand/latest/rand/fn.rng.html) is an asymptotically-fast, automatically-seeded and reasonably strong generator available on all `std` targets
- Direct support for seeding generators from the [`getrandom` crate](https://crates.io/crates/getrandom)
- Direct support for seeding generators from the [getrandom] crate

With broad support for random value generation and random processes:

Expand Down Expand Up @@ -80,8 +80,7 @@ Rand is built with these features enabled by default:

- `std` enables functionality dependent on the `std` lib
- `alloc` (implied by `std`) enables functionality requiring an allocator
- `getrandom` (implied by `std`) is an optional dependency providing the code
behind `rngs::OsRng`
- `os_rng` (implied by `std`) enables `rngs::OsRng`, using the [getrandom] crate
- `std_rng` enables inclusion of `StdRng`, `ThreadRng`

Optionally, the following dependencies can be enabled:
Expand All @@ -101,23 +100,23 @@ experimental `simd_support` feature.

Rand supports limited functionality in `no_std` mode (enabled via
`default-features = false`). In this case, `OsRng` and `from_os_rng` are
unavailable (unless `getrandom` is enabled), large parts of `seq` are
unavailable (unless `os_rng` is enabled), large parts of `seq` are
unavailable (unless `alloc` is enabled), and `ThreadRng` is unavailable.

## Portability and platform support

Many (but not all) algorithms are intended to have reproducible output. Read more in the book: [Portability](https://rust-random.github.io/book/portability.html).

The Rand library supports a variety of CPU architectures. Platform integration is outsourced to [getrandom](https://docs.rs/getrandom/latest/getrandom/).
The Rand library supports a variety of CPU architectures. Platform integration is outsourced to [getrandom].

### WASM support

Seeding entropy from OS on WASM target `wasm32-unknown-unknown` is not
*automatically* supported by `rand` or `getrandom`. If you are fine with
seeding the generator manually, you can disable the `getrandom` feature
seeding the generator manually, you can disable the `os_rng` feature
and use the methods on the `SeedableRng` trait. To enable seeding from OS,
either use a different target such as `wasm32-wasi` or add a direct
dependency on `getrandom` with the `js` feature (if the target supports
dependency on [getrandom] with the `js` feature (if the target supports
JavaScript). See
[getrandom#WebAssembly support](https://docs.rs/getrandom/latest/getrandom/#webassembly-support).

Expand All @@ -128,3 +127,5 @@ Apache License (Version 2.0).

See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT), and
[COPYRIGHT](COPYRIGHT) for details.

[getrandom]: https://crates.io/crates/getrandom
1 change: 1 addition & 0 deletions rand_chacha/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
- The `serde1` feature has been renamed `serde` (#1477)
- Rename feature `getrandom` to `os_rng`

## [0.9.0-alpha.1] - 2024-03-18

Expand Down
4 changes: 2 additions & 2 deletions rand_chacha/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ serde = { version = "1.0", features = ["derive"], optional = true }
[dev-dependencies]
# Only to test serde
serde_json = "1.0"
rand_core = { path = "../rand_core", version = "=0.9.0-alpha.1", features = ["getrandom"] }
rand_core = { path = "../rand_core", version = "=0.9.0-alpha.1", features = ["os_rng"] }

[features]
default = ["std"]
getrandom = ["rand_core/getrandom"]
os_rng = ["rand_core/os_rng"]
std = ["ppv-lite86/std", "rand_core/std"]
serde = ["dep:serde"]
2 changes: 1 addition & 1 deletion rand_chacha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Links:
`rand_chacha` is `no_std` compatible when disabling default features; the `std`
feature can be explicitly required to re-enable `std` support. Using `std`
allows detection of CPU features and thus better optimisation. Using `std`
also enables `getrandom` functionality, such as `ChaCha20Rng::from_os_rng()`.
also enables `os_rng` functionality, such as `ChaCha20Rng::from_os_rng()`.


# License
Expand Down
1 change: 1 addition & 0 deletions rand_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- Bump the MSRV to 1.63.0
- The `serde1` feature has been renamed `serde` (#1477)
- Rename feature `getrandom` to `os_rng`

## [0.9.0-alpha.1] - 2024-03-18

Expand Down
2 changes: 1 addition & 1 deletion rand_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ all-features = true
[features]
std = ["alloc", "getrandom?/std"]
alloc = [] # enables Vec and Box support without std
getrandom = ["dep:getrandom"]
os_rng = ["dep:getrandom"]
serde = ["dep:serde"] # enables serde for BlockRng wrapper

[dependencies]
Expand Down
12 changes: 5 additions & 7 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@ use core::{fmt, ops::DerefMut};
pub mod block;
pub mod impls;
pub mod le;
#[cfg(feature = "getrandom")]
#[cfg(feature = "os_rng")]
mod os;

#[cfg(feature = "getrandom")]
pub use getrandom;
#[cfg(feature = "getrandom")]
pub use os::OsRng;
#[cfg(feature = "os_rng")]
pub use os::{OsError, OsRng};

/// Implementation-level interface for RNGs
///
Expand Down Expand Up @@ -495,7 +493,7 @@ pub trait SeedableRng: Sized {
///
/// [`getrandom`]: https://docs.rs/getrandom
/// [`try_from_os_rng`]: SeedableRng::try_from_os_rng
#[cfg(feature = "getrandom")]
#[cfg(feature = "os_rng")]
fn from_os_rng() -> Self {
match Self::try_from_os_rng() {
Ok(res) => res,
Expand All @@ -511,7 +509,7 @@ pub trait SeedableRng: Sized {
/// `from_rng(&mut rand::rng()).unwrap()`.
///
/// [`getrandom`]: https://docs.rs/getrandom
#[cfg(feature = "getrandom")]
#[cfg(feature = "os_rng")]
fn try_from_os_rng() -> Result<Self, getrandom::Error> {
let mut seed = Self::Seed::default();
getrandom::getrandom(seed.as_mut())?;
Expand Down
53 changes: 48 additions & 5 deletions rand_core/src/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use getrandom::getrandom;
/// [getrandom] documentation for details.
///
/// This struct is available as `rand_core::OsRng` and as `rand::rngs::OsRng`.
/// In both cases, this requires the crate feature `getrandom` or `std`
/// In both cases, this requires the crate feature `os_rng` or `std`
/// (enabled by default in `rand` but not in `rand_core`).
///
/// # Blocking and error handling
Expand Down Expand Up @@ -47,26 +47,69 @@ use getrandom::getrandom;
#[derive(Clone, Copy, Debug, Default)]
pub struct OsRng;

/// Error type of [`OsRng`]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct OsError(getrandom::Error);

impl core::fmt::Display for OsError {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}

// NOTE: this can use core::error::Error from rustc 1.81.0
#[cfg(feature = "std")]
impl std::error::Error for OsError {
#[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
std::error::Error::source(&self.0)
}
}

impl OsError {
/// Extract the raw OS error code (if this error came from the OS)
///
/// This method is identical to [`std::io::Error::raw_os_error()`][1], except
/// that it works in `no_std` contexts. If this method returns `None`, the
/// error value can still be formatted via the `Display` implementation.
///
/// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error
#[inline]
pub fn raw_os_error(self) -> Option<i32> {
self.0.raw_os_error()
}

/// Extract the bare error code.
///
/// This code can either come from the underlying OS, or be a custom error.
/// Use [`OsError::raw_os_error()`] to disambiguate.
#[inline]
pub const fn code(self) -> core::num::NonZeroU32 {
self.0.code()
}
}

impl TryRngCore for OsRng {
type Error = getrandom::Error;
type Error = OsError;

#[inline]
fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
let mut buf = [0u8; 4];
getrandom(&mut buf)?;
getrandom(&mut buf).map_err(OsError)?;
Ok(u32::from_ne_bytes(buf))
}

#[inline]
fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
let mut buf = [0u8; 8];
getrandom(&mut buf)?;
getrandom(&mut buf).map_err(OsError)?;
Ok(u64::from_ne_bytes(buf))
}

#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
getrandom(dest)?;
getrandom(dest).map_err(OsError)?;
Ok(())
}
}
Expand Down
1 change: 1 addition & 0 deletions rand_pcg/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
- The `serde1` feature has been renamed `serde` (#1477)
- Rename feature `getrandom` to `os_rng`

## [0.9.0-alpha.1] - 2024-03-18

Expand Down
4 changes: 2 additions & 2 deletions rand_pcg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ rustdoc-args = ["--generate-link-to-definition"]

[features]
serde = ["dep:serde"]
getrandom = ["rand_core/getrandom"]
os_rng = ["rand_core/os_rng"]

[dependencies]
rand_core = { path = "../rand_core", version = "=0.9.0-alpha.1" }
Expand All @@ -32,4 +32,4 @@ serde = { version = "1", features = ["derive"], optional = true }
# deps yet, see: https://github.com/rust-lang/cargo/issues/1596
# Versions prior to 1.1.4 had incorrect minimal dependencies.
bincode = { version = "1.1.4" }
rand_core = { path = "../rand_core", version = "=0.9.0-alpha.1", features = ["getrandom"] }
rand_core = { path = "../rand_core", version = "=0.9.0-alpha.1", features = ["os_rng"] }
22 changes: 11 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ pub mod rngs;
pub mod seq;

// Public exports
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
pub use crate::rngs::thread::rng;

/// Access the thread-local generator
///
/// Use [`rand::rng()`](rng()) instead.
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
#[deprecated(since = "0.9.0", note = "renamed to `rng`")]
#[inline]
pub fn thread_rng() -> crate::rngs::ThreadRng {
Expand All @@ -118,7 +118,7 @@ pub fn thread_rng() -> crate::rngs::ThreadRng {

pub use rng::{Fill, Rng};

#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
use crate::distr::{Distribution, StandardUniform};

/// Generate a random value using the thread-local random number generator.
Expand Down Expand Up @@ -159,7 +159,7 @@ use crate::distr::{Distribution, StandardUniform};
///
/// [`StandardUniform`]: distr::StandardUniform
/// [`ThreadRng`]: rngs::ThreadRng
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
#[inline]
pub fn random<T>() -> T
where
Expand All @@ -179,7 +179,7 @@ where
/// let v: Vec<i32> = rand::random_iter().take(5).collect();
/// println!("{v:?}");
/// ```
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
#[inline]
pub fn random_iter<T>() -> distr::DistIter<StandardUniform, rngs::ThreadRng, T>
where
Expand All @@ -204,7 +204,7 @@ where
/// ```
/// Note that the first example can also be achieved (without `collect`'ing
/// to a `Vec`) using [`seq::IteratorRandom::choose`].
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
#[inline]
pub fn random_range<T, R>(range: R) -> T
where
Expand All @@ -228,7 +228,7 @@ where
/// # Panics
///
/// If `p < 0` or `p > 1`.
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
#[inline]
#[track_caller]
pub fn random_bool(p: f64) -> bool {
Expand Down Expand Up @@ -260,7 +260,7 @@ pub fn random_bool(p: f64) -> bool {
/// ```
///
/// [`Bernoulli`]: distr::Bernoulli
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
#[inline]
#[track_caller]
pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
Expand All @@ -282,7 +282,7 @@ pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
/// Note that you can instead use [`random()`] to generate an array of random
/// data, though this is slower for small elements (smaller than the RNG word
/// size).
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
#[inline]
#[track_caller]
pub fn fill<T: Fill + ?Sized>(dest: &mut T) {
Expand All @@ -302,7 +302,7 @@ mod test {
}

#[test]
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
fn test_random() {
let _n: u64 = random();
let _f: f32 = random();
Expand All @@ -316,7 +316,7 @@ mod test {
}

#[test]
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[cfg(all(feature = "std", feature = "std_rng", feature = "os_rng"))]
fn test_range() {
let _n: usize = random_range(42..=43);
let _f: f32 = random_range(42.0..43.0);
Expand Down
Loading

0 comments on commit 0ff946c

Please sign in to comment.