Skip to content

Document error cases and edge-case behavior of IndexedRandom sampling methods#1811

Open
teddytennant wants to merge 1 commit into
rust-random:masterfrom
teddytennant:indexed-random-sampling-docs
Open

Document error cases and edge-case behavior of IndexedRandom sampling methods#1811
teddytennant wants to merge 1 commit into
rust-random:masterfrom
teddytennant:indexed-random-sampling-docs

Conversation

@teddytennant

Copy link
Copy Markdown
Contributor

What

Documents the error cases and edge-case behavior of the IndexedRandom sampling methods in src/seq/slice.rs, with doc-test assertions where the behavior is easy to demonstrate:

  • choose_weighted / choose_weighted_mut / choose_weighted_iter: state that error cases are those of WeightedIndex::new — in particular WeightError::InvalidInput for an empty slice and WeightError::InsufficientNonZero when all weights are zero. The choose_weighted example now asserts both.
  • sample_weighted: document the WeightError::InvalidWeight case (matching the wording on index::sample_weighted) and that amount is clamped to self.len().
  • sample: document that amount is clamped to self.len(), with a doc-test asserting sample(&mut rng, 1000).count() == sample.len().
  • sample_array: document that None is returned if (and only if) N > self.len(), with a doc-test.

Why

Follow-up to #1783. That issue was about choose_weighted claiming to return None for empty sequences when it actually returns Err(WeightError::InvalidInput); the wrong claim was removed, but the docs were left saying nothing about when these methods error. Similarly, the clamping behavior of sample/sample_weighted and the None condition of sample_array were implemented but undocumented, so a reader had to consult the source (or index::sample*) to learn them.

Testing

  • cargo test --doc seq::slice — all 9 doc-tests pass, including the new/extended ones.
  • cargo fmt --check and cargo clippy --lib — clean.

Doc-only change; no function bodies are touched.

… methods

- choose_weighted, choose_weighted_mut, choose_weighted_iter: document
  that error cases are those of WeightedIndex::new, with doc-test
  assertions for the empty-slice and all-zero-weights cases
- sample_weighted: document the InvalidWeight error case (matching
  index::sample_weighted) and that amount is clamped to self.len()
- sample: document that amount is clamped to self.len(), with a doc-test
- sample_array: document that None is returned iff N > self.len(),
  with a doc-test

Follow-up to rust-random#1783.
Copilot AI review requested due to automatic review settings July 11, 2026 17:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dhardy dhardy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two lines are marginally useful. Most of this is just noise. (To a human who is able to read the docs in the intended docs.rs presentation format, including following links.)

Comment thread src/seq/slice.rs
/// Chooses `amount` elements from the slice at random, without repetition,
/// and in random order. The returned iterator is appropriate both for
/// collection into a `Vec` and filling an existing buffer (see example).
/// If `amount > self.len()`, `amount` is reduced to `self.len()`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/// If `amount > self.len()`, `amount` is reduced to `self.len()`.
/// If `amount > self.len()`, all available elements are sampled.

Comment thread src/seq/slice.rs
Comment on lines +112 to +114
///
/// // if the requested amount exceeds the length, every element is sampled:
/// assert_eq!(sample.sample(&mut rng, 1000).count(), sample.len());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
///
/// // if the requested amount exceeds the length, every element is sampled:
/// assert_eq!(sample.sample(&mut rng, 1000).count(), sample.len());

Comment thread src/seq/slice.rs
Comment on lines +145 to +148
///
/// // None is returned when more elements are requested than are available:
/// let b: Option<[u8; 32]> = sample.sample_array(&mut rng);
/// assert!(b.is_none());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
///
/// // None is returned when more elements are requested than are available:
/// let b: Option<[u8; 32]> = sample.sample_array(&mut rng);
/// assert!(b.is_none());

Comment thread src/seq/slice.rs
Comment on lines +172 to +175
/// Error cases are those of [`WeightedIndex::new`]; in particular, the
/// slice being empty results in [`WeightError::InvalidInput`] and all
/// weights being zero in [`WeightError::InsufficientNonZero`].
///

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is already documented by the return-type.

Suggested change
/// Error cases are those of [`WeightedIndex::new`]; in particular, the
/// slice being empty results in [`WeightError::InvalidInput`] and all
/// weights being zero in [`WeightError::InsufficientNonZero`].
///

Comment thread src/seq/slice.rs
///
/// ```
/// use rand::prelude::*;
/// use rand::seq::WeightError;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/// use rand::seq::WeightError;

Comment thread src/seq/slice.rs
Comment on lines +229 to +230
///
/// [`WeightedIndex::new`]: crate::distr::weighted::WeightedIndex::new

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
///
/// [`WeightedIndex::new`]: crate::distr::weighted::WeightedIndex::new

Comment thread src/seq/slice.rs
/// elements are never returned; the result may therefore contain fewer
/// elements than `amount` even when `self.len() >= amount`. The elements
/// are returned in an arbitrary, unspecified order.
/// If `amount > self.len()`, `amount` is reduced to `self.len()`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This behaviour is documented in sample which is linked here.

Suggested change
/// If `amount > self.len()`, `amount` is reduced to `self.len()`.

Comment thread src/seq/slice.rs
Comment on lines +261 to +263
/// Error cases:
/// - [`WeightError::InvalidWeight`] when a weight is not-a-number or negative.
///

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/// Error cases:
/// - [`WeightError::InvalidWeight`] when a weight is not-a-number or negative.
///

Comment thread src/seq/slice.rs
Comment on lines +391 to +394
/// Error cases are those of [`WeightedIndex::new`]; in particular, the
/// slice being empty results in [`WeightError::InvalidInput`] and all
/// weights being zero in [`WeightError::InsufficientNonZero`].
///

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/// Error cases are those of [`WeightedIndex::new`]; in particular, the
/// slice being empty results in [`WeightError::InvalidInput`] and all
/// weights being zero in [`WeightError::InsufficientNonZero`].
///

Comment thread src/seq/slice.rs
/// [`choose_mut`]: IndexedMutRandom::choose_mut
/// [`choose_weighted`]: IndexedRandom::choose_weighted
/// [`WeightedIndex`]: crate::distr::weighted::WeightedIndex
/// [`WeightedIndex::new`]: crate::distr::weighted::WeightedIndex::new

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/// [`WeightedIndex::new`]: crate::distr::weighted::WeightedIndex::new

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants