From 9f98d8ffb0fb3d12a0f718585d2ceb595e632eef Mon Sep 17 00:00:00 2001 From: qoh <1732901+qoh@users.noreply.github.com> Date: Tue, 21 Jan 2020 01:37:56 +0100 Subject: [PATCH] Impl Distribution for Alphanumeric Sampling a random alphanumeric string by collecting chars (that are known to be ASCII) into a String involves re-allocation as String is encoding to UTF-8, via the example: ```rust let chars: String = iter::repeat(()) .map(|()| rng.sample(Alphanumeric)) .take(7) .collect(); ``` I wanted to get rid of the clearly unnecessary re-allocations in my applications, so I needed to be able to access to the ASCII characters as simple bytes. It seems like that was already what was going on inside Alphanumeric however, it was just internal. This PR changes the `Distribution` impl to provide `u8`s (which it generates internally) instead, and implements the previous `Distribution` using it. One could then, for example, do this: ```rust let mut rng = thread_rng(); let bytes = (0..7).map(|_| rng.sample(ByteAlphanumeric)).collect(); let chars = unsafe { String::from_utf8_unchecked(bytes) }; ``` --- src/distributions/other.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/distributions/other.rs b/src/distributions/other.rs index c95060e5104..572095e5326 100644 --- a/src/distributions/other.rs +++ b/src/distributions/other.rs @@ -16,7 +16,7 @@ use crate::Rng; // ----- Sampling distributions ----- -/// Sample a `char`, uniformly distributed over ASCII letters and numbers: +/// Sample a `char` or `u8`, uniformly distributed over ASCII letters and numbers: /// a-z, A-Z and 0-9. /// /// # Example @@ -62,6 +62,13 @@ impl Distribution for Standard { impl Distribution for Alphanumeric { fn sample(&self, rng: &mut R) -> char { + let byte: u8 = self.sample(rng); + byte as char + } +} + +impl Distribution for Alphanumeric { + fn sample(&self, rng: &mut R) -> u8 { const RANGE: u32 = 26 + 26 + 10; const GEN_ASCII_STR_CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz\ @@ -73,7 +80,7 @@ impl Distribution for Alphanumeric { loop { let var = rng.next_u32() >> (32 - 6); if var < RANGE { - return GEN_ASCII_STR_CHARSET[var as usize] as char; + return GEN_ASCII_STR_CHARSET[var as usize]; } } }