pkce_std/
generate.rs

1//! Generating random bytes and strings.
2//!
3//! This module provides two functions for generating random bytes and strings:
4//! [`bytes`] and [`string`] accepting the desired length as [`Count`] and [`Length`] respectively.
5//!
6//! Because of the imposed length restrictions, the functions are safe to use
7//! in the context of this crate. See [`count`] and [`length`] for more information.
8//!
9//! [`count`]: crate::count
10//! [`length`]: crate::length
11
12#[cfg(feature = "unsafe-assert")]
13use std::hint::assert_unchecked;
14
15use rand::{Rng, RngCore, distr::Uniform, rng};
16
17use crate::{
18    check::chars::{CHARS, LENGTH},
19    count::Count,
20    length::Length,
21};
22
23/// Generates `count` random bytes.
24pub fn bytes(count: Count) -> Vec<u8> {
25    let mut data = vec![0; count.get()];
26
27    rng().fill_bytes(&mut data);
28
29    data
30}
31
32/// Generates random strings of `length` characters from the [`CHARS`] set.
33///
34/// # Panics
35///
36/// This function will not panic, as detailed below.
37///
38/// ## Distribution
39///
40/// The uniform distribution is created with constantly checked [`LENGTH`] being non-zero.
41///
42/// ## Bounds
43///
44/// [`CHARS`] is the array containing exactly [`LENGTH`] characters. Since the uniform range
45/// is exclusive, the sampled index will always be in the bounds of the array.
46///
47/// ## Feature
48///
49/// Moreover, the `unsafe-assert` feature can be enabled to `assume` the bounds are correct.
50pub fn string(length: Length) -> String {
51    let distribution = Uniform::new(0, LENGTH).unwrap();
52
53    rng()
54        .sample_iter(distribution)
55        .take(length.get())
56        .map(|index| {
57            #[cfg(feature = "unsafe-assert")]
58            unsafe {
59                assert_unchecked(index < LENGTH);
60            }
61
62            CHARS[index]
63        })
64        .collect()
65}