1#[cfg(not(all(
2 any(target_arch = "wasm32", target_arch = "wasm64"),
3 target_os = "unknown"
4)))]
5use std::time;
6
7use std::sync::atomic::{AtomicU64, Ordering};
8
9use super::Duration;
10
11static RECENT: AtomicU64 = AtomicU64::new(0);
12
13#[cfg(all(
14 any(target_arch = "wasm32", target_arch = "wasm64"),
15 target_os = "unknown"
16))]
17mod js_imports {
18 use wasm_bindgen::prelude::*;
19
20 #[wasm_bindgen]
21 extern "C" {
22 pub type Date;
23
24 #[wasm_bindgen(static_method_of = Date)]
25 pub fn now() -> f64;
26 }
27}
28
29#[derive(Debug)]
31pub struct Clock;
32
33pub type UnixTimeStamp = Duration;
35
36impl Clock {
37 #[inline]
39 pub fn now_since_epoch() -> UnixTimeStamp {
40 Duration::from_u64(unix_ts())
41 }
42
43 #[inline]
46 pub fn recent_since_epoch() -> UnixTimeStamp {
47 Duration::from_u64(RECENT.load(Ordering::Relaxed))
48 }
49
50 #[inline]
55 pub fn update() {
56 let now = unix_ts();
57 RECENT.store(now, Ordering::Relaxed)
58 }
59
60 pub fn set_recent_since_epoch(recent: UnixTimeStamp) {
64 RECENT.store(recent.as_u64(), Ordering::Relaxed)
65 }
66}
67
68#[cfg(all(
69 any(target_arch = "wasm32", target_arch = "wasm64"),
70 target_os = "unknown"
71))]
72#[inline]
73fn unix_ts() -> u64 {
74 let unix_ts_now_sys = (js_imports::Date::now() / 1000.0).round() as u64;
75 let unix_ts_now = Duration::from_secs(unix_ts_now_sys);
76 unix_ts_now.as_u64()
77}
78
79#[cfg(not(all(
80 any(target_arch = "wasm32", target_arch = "wasm64"),
81 target_os = "unknown"
82)))]
83#[inline]
84fn unix_ts() -> u64 {
85 let unix_ts_now_sys = time::SystemTime::now()
86 .duration_since(time::UNIX_EPOCH)
87 .expect("The system clock is not properly set");
88 let unix_ts_now = Duration::from(unix_ts_now_sys);
89 unix_ts_now.as_u64()
90}