1use std::{cell::UnsafeCell, rc::Rc};
2
3use rand::{RngCore, SeedableRng};
4use rand_xoshiro::Xoshiro256PlusPlus;
5
6type InternalGenerator = Rc<UnsafeCell<Xoshiro256PlusPlus>>;
7
8#[derive(Clone, Debug)]
9pub struct Random {
10 rng: InternalGenerator,
11}
12
13thread_local! {
14 static GENERATOR: InternalGenerator = {
15 let prng = Xoshiro256PlusPlus::from_entropy();
16
17 Rc::new(UnsafeCell::new(prng))
18 }
19}
20
21pub fn update_seed(seed: Option<u64>) {
23 let prng = match seed {
24 Some(internal_seed) => Xoshiro256PlusPlus::seed_from_u64(internal_seed),
25 None => Xoshiro256PlusPlus::from_entropy(),
26 };
27
28 GENERATOR.with(|t| {
29 let generator = unsafe { &mut *t.get() };
30 *generator = prng;
31 });
32}
33
34pub fn generator() -> Random {
35 let rng = GENERATOR.with(|t| t.clone());
36 Random { rng }
37}
38
39impl Default for Random {
40 fn default() -> Self {
41 generator()
42 }
43}
44
45impl RngCore for Random {
46 fn next_u32(&mut self) -> u32 {
47 let rng = unsafe { &mut *self.rng.get() };
48 rng.next_u32()
49 }
50
51 fn next_u64(&mut self) -> u64 {
52 let rng = unsafe { &mut *self.rng.get() };
53 rng.next_u64()
54 }
55
56 fn fill_bytes(&mut self, dest: &mut [u8]) {
57 let rng = unsafe { &mut *self.rng.get() };
58 rng.fill_bytes(dest)
59 }
60
61 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
62 let rng = unsafe { &mut *self.rng.get() };
63 rng.try_fill_bytes(dest)
64 }
65}