From 4364102e70bde35e82da153224150528d12c2bc3 Mon Sep 17 00:00:00 2001 From: Justus Fluegel Date: Sun, 3 Mar 2024 15:09:22 +0100 Subject: [PATCH 1/6] Add .choices() method to the Slice distribution Signed-off-by: Justus Fluegel --- src/distributions/slice.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/distributions/slice.rs b/src/distributions/slice.rs index 5fc08751f6..73bf326487 100644 --- a/src/distributions/slice.rs +++ b/src/distributions/slice.rs @@ -6,6 +6,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::num::NonZeroUsize; + use crate::distributions::{Distribution, Uniform}; #[cfg(feature = "alloc")] use alloc::string::String; @@ -81,6 +83,13 @@ impl<'a, T> Slice<'a, T> { }), } } + + /// Returns the count of choices in this distribution + pub fn choices(&self) -> NonZeroUsize { + // Safety: at construction time, it was ensured that the slice was + // non-empty, as such the length can never be 0. + unsafe { NonZeroUsize::new_unchecked(self.slice.len()) } + } } impl<'a, T> Distribution<&'a T> for Slice<'a, T> { From ebeaeb39f9965561b02f867410ea5dbeb353e67a Mon Sep 17 00:00:00 2001 From: Justus Fluegel Date: Sun, 3 Mar 2024 15:19:41 +0100 Subject: [PATCH 2/6] Add changelog entry (I hope this is correct?) Signed-off-by: Justus Fluegel --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aaccde2ce7..ee902a86bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md). You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.html) useful. +## [0.9.1] - unreleased +- Add the `Slice::choices` method to the Slice distribution (#1402) + ## [0.9.0-alpha.0] - 2024-02-18 This is a pre-release. To depend on this version, use `rand = "=0.9.0-alpha.0"` to prevent automatic updates (which can be expected to include breaking changes). From 5df12b19795f05a0508230f54c2b17142c304e3b Mon Sep 17 00:00:00 2001 From: Justus Fluegel Date: Sun, 3 Mar 2024 16:12:06 +0100 Subject: [PATCH 3/6] Rename Slice::choices() -> Slice::num_choices() Signed-off-by: Justus Fluegel --- CHANGELOG.md | 2 +- src/distributions/slice.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee902a86bd..b431a9ef73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md). You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.html) useful. ## [0.9.1] - unreleased -- Add the `Slice::choices` method to the Slice distribution (#1402) +- Add the `Slice::num_choices` method to the Slice distribution (#1402) ## [0.9.0-alpha.0] - 2024-02-18 This is a pre-release. To depend on this version, use `rand = "=0.9.0-alpha.0"` to prevent automatic updates (which can be expected to include breaking changes). diff --git a/src/distributions/slice.rs b/src/distributions/slice.rs index 73bf326487..ef7488a880 100644 --- a/src/distributions/slice.rs +++ b/src/distributions/slice.rs @@ -85,7 +85,7 @@ impl<'a, T> Slice<'a, T> { } /// Returns the count of choices in this distribution - pub fn choices(&self) -> NonZeroUsize { + pub fn num_choices(&self) -> NonZeroUsize { // Safety: at construction time, it was ensured that the slice was // non-empty, as such the length can never be 0. unsafe { NonZeroUsize::new_unchecked(self.slice.len()) } From 1f08009952831cee464bd118d3dbdb97a64ff932 Mon Sep 17 00:00:00 2001 From: Justus Fluegel Date: Tue, 5 Mar 2024 18:04:53 +0100 Subject: [PATCH 4/6] Use choices struct field at creation time instead of using unsafe at call time Signed-off-by: Justus Fluegel --- src/distributions/slice.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/distributions/slice.rs b/src/distributions/slice.rs index ef7488a880..7128a881f9 100644 --- a/src/distributions/slice.rs +++ b/src/distributions/slice.rs @@ -69,26 +69,28 @@ use alloc::string::String; pub struct Slice<'a, T> { slice: &'a [T], range: Uniform, + choices: NonZeroUsize, } impl<'a, T> Slice<'a, T> { /// Create a new `Slice` instance which samples uniformly from the slice. /// Returns `Err` if the slice is empty. pub fn new(slice: &'a [T]) -> Result { - match slice.len() { - 0 => Err(EmptySlice), - len => Ok(Self { - slice, - range: Uniform::new(0, len).unwrap(), - }), - } + let len = match NonZeroUsize::new(slice.len()) { + None => return Err(EmptySlice), + Some(len) => len, + }; + + Ok(Self { + slice, + range: Uniform::new(0, len.get()).unwrap(), + choices: len, + }) } /// Returns the count of choices in this distribution pub fn num_choices(&self) -> NonZeroUsize { - // Safety: at construction time, it was ensured that the slice was - // non-empty, as such the length can never be 0. - unsafe { NonZeroUsize::new_unchecked(self.slice.len()) } + self.choices } } From f8b8b775945180e1fd112839561f0540c838a534 Mon Sep 17 00:00:00 2001 From: Justus Fluegel Date: Tue, 5 Mar 2024 21:37:32 +0100 Subject: [PATCH 5/6] Use ? instead of match Signed-off-by: Justus Fluegel --- src/distributions/slice.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/distributions/slice.rs b/src/distributions/slice.rs index 7128a881f9..ef652ce514 100644 --- a/src/distributions/slice.rs +++ b/src/distributions/slice.rs @@ -76,10 +76,7 @@ impl<'a, T> Slice<'a, T> { /// Create a new `Slice` instance which samples uniformly from the slice. /// Returns `Err` if the slice is empty. pub fn new(slice: &'a [T]) -> Result { - let len = match NonZeroUsize::new(slice.len()) { - None => return Err(EmptySlice), - Some(len) => len, - }; + let len = NonZeroUsize::new(slice.len()).ok_or(EmptySlice)?; Ok(Self { slice, From 41b044a5491b39e65e37fc946fde6eb002ff8fd1 Mon Sep 17 00:00:00 2001 From: Justus Fluegel Date: Tue, 5 Mar 2024 21:42:48 +0100 Subject: [PATCH 6/6] Name field better Signed-off-by: Justus Fluegel --- src/distributions/slice.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/distributions/slice.rs b/src/distributions/slice.rs index ef652ce514..1c96680aa6 100644 --- a/src/distributions/slice.rs +++ b/src/distributions/slice.rs @@ -69,25 +69,25 @@ use alloc::string::String; pub struct Slice<'a, T> { slice: &'a [T], range: Uniform, - choices: NonZeroUsize, + num_choices: NonZeroUsize, } impl<'a, T> Slice<'a, T> { /// Create a new `Slice` instance which samples uniformly from the slice. /// Returns `Err` if the slice is empty. pub fn new(slice: &'a [T]) -> Result { - let len = NonZeroUsize::new(slice.len()).ok_or(EmptySlice)?; + let num_choices = NonZeroUsize::new(slice.len()).ok_or(EmptySlice)?; Ok(Self { slice, - range: Uniform::new(0, len.get()).unwrap(), - choices: len, + range: Uniform::new(0, num_choices.get()).unwrap(), + num_choices, }) } /// Returns the count of choices in this distribution pub fn num_choices(&self) -> NonZeroUsize { - self.choices + self.num_choices } }