Skip to content

Commit

Permalink
added char() implementations and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BartMassey committed Jan 8, 2022
1 parent 68977d8 commit afc1d51
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,67 @@ impl Rng {
let i = self.u8(..len);
CHARS[i as usize] as char
}

/// Generates a random `char` in the given range.
///
/// Panics if the range is empty.
#[inline]
pub fn char(&self, range: impl RangeBounds<char>) -> char {
use std::convert::{TryFrom, TryInto};

let panic_empty_range = || {
panic!(
"empty range: {:?}..{:?}",
range.start_bound(),
range.end_bound()
)
};

let surrogate_start = 0xd800u32;
let surrogate_len = 0x800u32;

let low = match range.start_bound() {
Bound::Unbounded => 0u8 as char,
Bound::Included(&x) => x,
Bound::Excluded(&x) => {
let scalar = if x as u32 == surrogate_start - 1 {
surrogate_start + surrogate_len
} else {
x as u32 + 1
};
char::try_from(scalar).unwrap_or_else(|_| panic_empty_range())
}
};

let high = match range.end_bound() {
Bound::Unbounded => std::char::MAX,
Bound::Included(&x) => x,
Bound::Excluded(&x) => {
let scalar = if x as u32 == surrogate_start + surrogate_len {
surrogate_start - 1
} else {
(x as u32).wrapping_sub(1)
};
char::try_from(scalar).unwrap_or_else(|_| panic_empty_range())
}
};

if low > high {
panic_empty_range();
}

let gap = if (low as u32) < surrogate_start && (high as u32) >= surrogate_start {
surrogate_len
} else {
0
};
let range = high as u32 - low as u32 - gap;
let mut val = self.u32(0..=range) + low as u32;
if val >= surrogate_start {
val += gap;
}
val.try_into().unwrap()
}
}

/// Initializes the thread-local generator with the given seed.
Expand Down Expand Up @@ -594,6 +655,7 @@ integer!(u128, "Generates a random `u128` in the given range.");
integer!(i128, "Generates a random `i128` in the given range.");
integer!(usize, "Generates a random `usize` in the given range.");
integer!(isize, "Generates a random `isize` in the given range.");
integer!(char, "Generates a random `char` in the given range.");

/// Generates a random `f32` in range `0..1`.
pub fn f32() -> f32 {
Expand Down

0 comments on commit afc1d51

Please sign in to comment.