1use chrono::{DateTime, Duration, Utc};
2use rand::prelude::*;
3use rand_chacha::ChaCha8Rng;
4
5pub struct DeterministicRng {
7 rng: ChaCha8Rng,
8}
9
10impl DeterministicRng {
11 pub fn new(seed: u64) -> Self {
12 Self {
13 rng: ChaCha8Rng::seed_from_u64(seed),
14 }
15 }
16
17 pub fn next_u64(&mut self) -> u64 {
18 self.rng.next_u64()
19 }
20}
21
22pub struct Clock {
24 frozen_time: Option<DateTime<Utc>>,
25}
26
27impl Default for Clock {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33impl Clock {
34 pub fn new() -> Self {
35 Self { frozen_time: None }
36 }
37
38 pub fn now(&self) -> DateTime<Utc> {
39 self.frozen_time.unwrap_or_else(Utc::now)
40 }
41
42 pub fn freeze(&mut self, time: DateTime<Utc>) {
43 self.frozen_time = Some(time);
44 }
45
46 pub fn advance(&mut self, duration: Duration) {
47 if let Some(time) = &mut self.frozen_time {
48 *time += duration;
49 }
50 }
51}