1#![cfg_attr(not(feature = "std"), no_std)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![cfg_attr(docsrs, allow(unused_attributes))]
5#![deny(missing_docs, warnings)]
6#![forbid(unsafe_code)]
7
8pub use core::sync::atomic::Ordering;
9
10use portable_atomic::AtomicU128;
11
12mod duration;
13pub use duration::AtomicDuration;
14mod option_duration;
15pub use option_duration::AtomicOptionDuration;
16
17pub mod utils {
19 #[cfg(feature = "std")]
20 use std::time::{Duration, Instant, SystemTime};
21
22 #[cfg(feature = "std")]
23 fn init() -> (Duration, Instant) {
24 static ONCE: std::sync::OnceLock<(Duration, Instant)> = std::sync::OnceLock::new();
25
26 *ONCE.get_or_init(|| {
27 let epoch_dur = SystemTime::now()
28 .duration_since(SystemTime::UNIX_EPOCH)
29 .unwrap();
30 let instant_now = Instant::now();
31 (epoch_dur, instant_now)
32 })
33 }
34
35 #[cfg(feature = "std")]
37 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
38 #[cfg_attr(not(tarpaulin), inline(always))]
39 pub fn encode_instant_to_duration(instant: Instant) -> Duration {
40 let (epoch_dur, instant_now) = init();
41 if instant <= instant_now {
42 epoch_dur - (instant_now - instant)
43 } else {
44 epoch_dur + (instant - instant_now)
45 }
46 }
47
48 #[cfg(feature = "std")]
57 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
58 #[cfg_attr(not(tarpaulin), inline(always))]
59 pub fn decode_instant_from_duration(duration: Duration) -> Instant {
60 let (epoch_dur, instant_now) = init();
61 if duration >= epoch_dur {
62 let delta = duration - epoch_dur;
63 instant_now.checked_add(delta).unwrap_or(instant_now)
70 } else {
71 let delta = epoch_dur - duration;
72 instant_now.checked_sub(delta).unwrap_or(instant_now)
73 }
74 }
75
76 pub use super::duration::{decode_duration, encode_duration};
77 pub use super::option_duration::{decode_option_duration, encode_option_duration};
78}
79
80#[cfg(feature = "std")]
81mod system_time;
82
83#[cfg(feature = "std")]
84#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
85pub use system_time::AtomicSystemTime;
86
87#[cfg(feature = "std")]
88mod option_system_time;
89#[cfg(feature = "std")]
90#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
91pub use option_system_time::AtomicOptionSystemTime;
92
93#[cfg(feature = "std")]
94mod instant;
95#[cfg(feature = "std")]
96#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
97pub use instant::AtomicInstant;
98
99#[cfg(feature = "std")]
100mod option_instant;
101#[cfg(feature = "std")]
102#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
103pub use option_instant::AtomicOptionInstant;
104
105#[cfg(feature = "std")]
106use utils::{decode_instant_from_duration, encode_instant_to_duration};