Skip to content
Open
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
41 changes: 36 additions & 5 deletions library/core/src/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@ pub trait RandomSource {
/// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw
/// part of it away if not needed.
fn fill_bytes(&mut self, bytes: &mut [u8]);

/// Returns a random 32-bit integer.
///
/// The default implementation uses `fill_bytes` and interprets those bytes as integer, but this

@juntyr juntyr Jun 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The default implementation uses `fill_bytes` and interprets those bytes as integer, but this
/// The default implementation uses `fill_bytes` and interprets those bytes as a little-endian integer, but this

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the question is whether we want to promise this, or reserve the right to change it (at least before stabilization, but maybe even later). Personally I think native-endian isn't worth the portability hazard and little-endian is a good default, but I've already seen one comment above advocating for native-endian.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For context, rand uses LE conversions and I don't recall ever receiving any criticism/complaints regarding this choice. Possibly because there isn't much BE hardware about today (or at least, not much intersection of Rust and BE systems).

/// is not guaranteed. A `RandomSource` can override this method to behave differently, e.g., it
/// may skip parts of its internal buffer to avoid the need for an unaligned load.
#[inline]
fn next_u32(&mut self) -> u32 {
let mut buf = [0; size_of::<u32>()];
self.fill_bytes(&mut buf);
u32::from_le_bytes(buf)
}

/// Returns a random 64-bit integer.
///
/// The default implementation uses `fill_bytes` and interprets those bytes as integer, but this

@juntyr juntyr Jun 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The default implementation uses `fill_bytes` and interprets those bytes as integer, but this
/// The default implementation uses `fill_bytes` and interprets those bytes as a little-endian integer, but this

View changes since the review

/// is not guaranteed. A `RandomSource` can override this method to behave differently, e.g., it
/// may skip parts of its internal buffer to avoid the need for an unaligned load.
#[inline]
fn next_u64(&mut self) -> u64 {
let mut buf = [0; size_of::<u64>()];
self.fill_bytes(&mut buf);
u64::from_le_bytes(buf)
}
}

/// A trait representing a distribution of random values for a type.
Expand All @@ -35,12 +59,19 @@ impl Distribution<bool> for RangeFull {
}

macro_rules! impl_primitive {
($t:ty, $method:ident) => {
impl Distribution<$t> for RangeFull {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t {
source.$method() as $t
}
}
};
($t:ty) => {
impl Distribution<$t> for RangeFull {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t {
let mut bytes = (0 as $t).to_ne_bytes();
source.fill_bytes(&mut bytes);
<$t>::from_ne_bytes(bytes)
<$t>::from_le_bytes(bytes)
}
}
};
Expand All @@ -50,10 +81,10 @@ impl_primitive!(u8);
impl_primitive!(i8);
impl_primitive!(u16);
impl_primitive!(i16);
impl_primitive!(u32);
impl_primitive!(i32);
impl_primitive!(u64);
impl_primitive!(i64);
impl_primitive!(u32, next_u32);
impl_primitive!(i32, next_u32);
impl_primitive!(u64, next_u64);
impl_primitive!(i64, next_u64);
impl_primitive!(u128);
impl_primitive!(i128);
impl_primitive!(usize);
Expand Down
Loading