tuwunel_core/utils/
rand.rs1use std::{
2 ops::Range,
3 time::{Duration, SystemTime},
4};
5
6use arrayvec::ArrayString;
7use rand::{RngExt, rng, seq::SliceRandom};
8use ruma::OwnedEventId;
9
10pub fn shuffle<T>(vec: &mut [T]) {
11 let mut rng = rng();
12 vec.shuffle(&mut rng);
13}
14
15pub fn string(length: usize) -> String {
16 rng()
17 .sample_iter(&rand::distr::Alphanumeric)
18 .take(length)
19 .map(char::from)
20 .collect()
21}
22
23#[inline]
24pub fn string_array<const LENGTH: usize>() -> ArrayString<LENGTH> {
25 let mut ret = ArrayString::<LENGTH>::new();
26 rng()
27 .sample_iter(&rand::distr::Alphanumeric)
28 .take(LENGTH)
29 .map(char::from)
30 .for_each(|c| ret.push(c));
31
32 ret
33}
34
35#[must_use]
36pub fn event_id() -> OwnedEventId {
37 use base64::{
38 Engine,
39 alphabet::URL_SAFE,
40 engine::{GeneralPurpose, general_purpose::NO_PAD},
41 };
42
43 let mut binary: [u8; 32] = [0; _];
44 rand::fill(&mut binary);
45
46 let mut encoded: [u8; 43] = [0; _];
47 GeneralPurpose::new(&URL_SAFE, NO_PAD)
48 .encode_slice(binary, &mut encoded)
49 .expect("Failed to encode binary to base64");
50
51 let event_id: &str = str::from_utf8(&encoded)
52 .expect("Failed to convert array of base64 bytes to valid utf8 str");
53
54 OwnedEventId::from_parts('$', event_id, None)
55 .expect("Failed to generate valid random event_id")
56}
57
58#[must_use]
59pub fn truncate_string(mut str: String, range: Range<u64>) -> String {
60 let len = rng()
61 .random_range(range)
62 .try_into()
63 .unwrap_or(usize::MAX);
64
65 if let Some((i, _)) = str.char_indices().nth(len) {
66 str.truncate(i);
67 }
68
69 str
70}
71
72#[inline]
73#[must_use]
74pub fn truncate_str(str: &str, range: Range<u64>) -> &str {
75 let len = rng()
76 .random_range(range)
77 .try_into()
78 .unwrap_or(usize::MAX);
79
80 str.char_indices()
81 .nth(len)
82 .map(|(i, _)| str.split_at(i).0)
83 .unwrap_or(str)
84}
85
86#[inline]
87#[must_use]
88pub fn time_from_now_secs(range: Range<u64>) -> SystemTime {
89 SystemTime::now()
90 .checked_add(secs(range))
91 .expect("range does not overflow SystemTime")
92}
93
94#[must_use]
95pub fn secs(range: Range<u64>) -> Duration {
96 let mut rng = rng();
97 Duration::from_secs(rng.random_range(range))
98}