Skip to main content

universal_time/
global.rs

1use crate::{Instant, SystemTime};
2
3/// Source of wall-clock timestamps.
4pub trait WallClock {
5    /// Returns the current wall-clock time.
6    fn system_time(&self) -> SystemTime;
7}
8
9/// Source of monotonic instants.
10pub trait MonotonicClock {
11    /// Returns the current monotonic instant.
12    fn instant(&self) -> Instant;
13}
14
15/// A full time context that can provide wall-clock and monotonic time.
16pub trait TimeProvider: WallClock + MonotonicClock + Sync {}
17
18impl<T> TimeProvider for T where T: WallClock + MonotonicClock + Sync {}
19
20// On platforms without std, users must provide the time provider symbol via define_time_provider! macro
21extern "Rust" {
22    #[link_name = "__universal_time_provider"]
23    static TIME_PROVIDER: &'static dyn TimeProvider;
24}
25
26#[inline(always)]
27pub(crate) fn get_time_provider() -> &'static dyn TimeProvider {
28    unsafe { TIME_PROVIDER }
29}
30
31/// Macro to define a custom time provider for no_std platforms.
32///
33/// This macro must be called in your binary crate when using this library on no_std
34/// or WASM unknown targets. Pass a static instance of your time provider.
35///
36/// # Example
37///
38/// ```
39/// use core::time::Duration;
40///
41/// use universal_time::{define_time_provider, Instant, MonotonicClock, SystemTime, WallClock};
42///
43/// struct MyTimeProvider;
44///
45/// impl WallClock for MyTimeProvider {
46///     fn system_time(&self) -> SystemTime {
47///         SystemTime::from_unix_duration(Duration::from_secs(0))
48///     }
49/// }
50///
51/// impl MonotonicClock for MyTimeProvider {
52///     fn instant(&self) -> Instant {
53///         Instant::from_ticks(Duration::from_secs(0))
54///     }
55/// }
56///
57/// define_time_provider!(MyTimeProvider);
58/// ```
59#[cfg_attr(
60    docsrs,
61    doc(cfg(any(
62        not(feature = "std"),
63        all(feature = "std", target_family = "wasm", target_os = "unknown")
64    )))
65)]
66#[macro_export]
67macro_rules! define_time_provider {
68    ($provider_instance:expr) => {
69        #[export_name = "__universal_time_provider"]
70        static __UNIVERSAL_TIME_PROVIDER: &dyn $crate::TimeProvider = &$provider_instance;
71    };
72}