use crate::{Cast, Char, Rand, RandTry, Result};
#[doc = crate::_tags!(rand construction)]
#[doc = crate::_doc_meta!{location("num/prob/rand")}]
pub trait FromRandTry: Sized {
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
}
#[doc = crate::_tags!(rand construction)]
#[doc = crate::_doc_meta!{location("num/prob/rand")}]
pub trait FromRand: FromRandTry {
#[must_use]
#[inline(always)]
fn from_rand<R: Rand + ?Sized>(rng: &mut R) -> Self {
match Self::from_rand_try(rng) {
Ok(value) => value,
Err(error) => match error {},
}
}
}
impl FromRandTry for bool {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_bool()
}
}
impl FromRandTry for char {
#[inline]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
let i = rng.rand_try_below(Char::SCALAR_COUNT as u64)? as u32;
let scalar = if i < Char::SURROGATE_START { i } else { i + Char::SURROGATE_COUNT };
match char::from_u32(scalar) {
Some(ch) => Ok(ch),
None => unreachable!("mapped value is always a valid Unicode scalar"),
}
}
}
impl FromRandTry for u8 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u8()
}
}
impl FromRandTry for u16 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u16()
}
}
impl FromRandTry for u32 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u32()
}
}
impl FromRandTry for u64 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u64()
}
}
impl FromRandTry for u128 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
let pair = [rng.rand_try_next_u64()?, rng.rand_try_next_u64()?];
Ok(Cast::<u128>::from_u64_le(pair))
}
}
impl FromRandTry for usize {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u64().map(|n| n as usize)
}
}
impl FromRandTry for i8 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u8().map(|n| n as i8)
}
}
impl FromRandTry for i16 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u16().map(|n| n as i16)
}
}
impl FromRandTry for i32 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u32().map(|n| n as i32)
}
}
impl FromRandTry for i64 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u64().map(|n| n as i64)
}
}
impl FromRandTry for i128 {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
let pair = [rng.rand_try_next_u64()?, rng.rand_try_next_u64()?];
Ok(Cast::<u128>::from_u64_le(pair) as i128)
}
}
impl FromRandTry for isize {
#[inline(always)]
fn from_rand_try<R: RandTry + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
rng.rand_try_next_u64().map(|n| n as isize)
}
}