1mod test_faketime;
3mod test_realtime;
4
5#[cfg(feature = "enable_faketime")]
6use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
7#[cfg(not(target_family = "wasm"))]
8pub use std::time::{Duration, Instant, SystemTime};
9#[cfg(all(target_family = "wasm", target_os = "unknown"))]
10pub use web_time::{Duration, Instant, SystemTime};
11
12#[cfg(feature = "enable_faketime")]
14static FAKETIME: AtomicU64 = AtomicU64::new(0);
15
16#[cfg(feature = "enable_faketime")]
18static FAKETIME_ENABLED: AtomicBool = AtomicBool::new(false);
19
20fn system_time_as_millis() -> u64 {
22    let duration = SystemTime::now()
23        .duration_since(SystemTime::UNIX_EPOCH)
24        .expect("SystemTime before UNIX EPOCH!");
25    duration.as_secs() * 1000 + u64::from(duration.subsec_millis())
26}
27
28#[cfg(not(feature = "enable_faketime"))]
30pub fn unix_time_as_millis() -> u64 {
31    system_time_as_millis()
32}
33
34#[cfg(feature = "enable_faketime")]
36pub fn faketime() -> FaketimeGuard {
37    FaketimeGuard {}
38}
39
40#[cfg(feature = "enable_faketime")]
42pub fn unix_time_as_millis() -> u64 {
43    if FAKETIME_ENABLED.load(Ordering::SeqCst) {
44        return FAKETIME.load(Ordering::SeqCst);
45    }
46    system_time_as_millis()
47}
48
49pub fn unix_time() -> Duration {
51    Duration::from_millis(unix_time_as_millis())
52}
53
54#[cfg(feature = "enable_faketime")]
57pub struct FaketimeGuard {}
58
59#[cfg(feature = "enable_faketime")]
60impl FaketimeGuard {
61    #[cfg(feature = "enable_faketime")]
63    pub fn set_faketime(&self, time: u64) {
64        FAKETIME.store(time, Ordering::Release);
65        FAKETIME_ENABLED.store(true, Ordering::SeqCst);
66    }
67
68    #[cfg(feature = "enable_faketime")]
70    pub fn disable_faketime(&self) {
71        FAKETIME_ENABLED.store(false, Ordering::Release);
72    }
73}
74
75#[cfg(feature = "enable_faketime")]
76impl Drop for FaketimeGuard {
77    fn drop(&mut self) {
78        self.disable_faketime()
79    }
80}