fm/common/
random.rs

1use std::collections::hash_map::RandomState;
2use std::hash::{BuildHasher, Hash, Hasher};
3
4/// Random seed generator
5/// From <https://blog.orhun.dev/zero-deps-random-in-rust/>
6fn random_seed() -> u64 {
7    RandomState::new().build_hasher().finish()
8}
9
10/// Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
11///
12/// <https://github.com/rust-lang/rust/blob/1.55.0/library/core/src/slice/sort.rs#L559-L573>
13/// From <https://blog.orhun.dev/zero-deps-random-in-rust/>
14fn random_numbers() -> impl Iterator<Item = u32> {
15    // let mut random = 92u32;
16    let mut random = random_seed() as u32;
17    std::iter::repeat_with(move || {
18        random ^= random << 13;
19        random ^= random >> 17;
20        random ^= random << 5;
21        random
22    })
23}
24
25pub fn random_alpha_chars() -> impl Iterator<Item = char> {
26    random_numbers()
27        .map(|r| (r & 255) as u8 as char)
28        .filter(|c| c.is_ascii_alphabetic())
29}
30
31fn hasher<T>(data: T) -> u64
32where
33    T: Hash,
34{
35    let mut hasher = std::hash::DefaultHasher::new();
36    data.hash(&mut hasher);
37    hasher.finish()
38}
39
40/// Hash a path (as `str, string, Cow<str>, Path, PathBuf`) into a predictable string.
41/// It will allow to check quickly if a file is already created.
42pub fn hash_path<P: AsRef<std::path::Path>>(p: P) -> String {
43    let h = hasher(p.as_ref());
44    h.to_string()
45}