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#[doc(hidden)]
21#[macro_export]
22macro_rules! __time_provider_link_name {
23 () => {
24 concat!(
25 "\n\nerror: a time provider is required.\n \
26 Use `define_time_provider!(YourProvider)` in your binary crate.\n \
27 See: ",
28 env!("CARGO_PKG_HOMEPAGE"),
29 "\n"
30 )
31 };
32}
33
34// On platforms without std, users must provide the time provider symbol via define_time_provider! macro
35extern "Rust" {
36 #[link_name = __time_provider_link_name!()]
37 static TIME_PROVIDER: &'static dyn TimeProvider;
38}
39
40#[inline(always)]
41pub(crate) fn get_time_provider() -> &'static dyn TimeProvider {
42 unsafe { TIME_PROVIDER }
43}
44
45/// Macro to define a custom time provider for no_std platforms.
46///
47/// This macro must be called in your binary crate when using this library on no_std
48/// or WASM unknown targets. Pass a static instance of your time provider.
49///
50/// # Example
51///
52/// ```
53/// use core::time::Duration;
54///
55/// use universal_time::{define_time_provider, Instant, MonotonicClock, SystemTime, WallClock};
56///
57/// struct MyTimeProvider;
58///
59/// impl WallClock for MyTimeProvider {
60/// fn system_time(&self) -> SystemTime {
61/// SystemTime::from_unix_duration(Duration::from_secs(0))
62/// }
63/// }
64///
65/// impl MonotonicClock for MyTimeProvider {
66/// fn instant(&self) -> Instant {
67/// Instant::from_ticks(Duration::from_secs(0))
68/// }
69/// }
70///
71/// define_time_provider!(MyTimeProvider);
72/// ```
73#[cfg_attr(
74 docsrs,
75 doc(cfg(any(
76 not(feature = "std"),
77 all(feature = "std", target_family = "wasm", target_os = "unknown")
78 )))
79)]
80#[macro_export]
81macro_rules! define_time_provider {
82 ($provider_instance:expr) => {
83 #[export_name = $crate::__time_provider_link_name!()]
84 static __UNIVERSAL_TIME_PROVIDER: &dyn $crate::TimeProvider = &$provider_instance;
85 };
86}