1pub use crate::instant::Instant;
2use std::time::Duration;
3
4#[cfg(not(target_arch = "wasm32"))]
5pub use std::time::SystemTime;
6
7#[cfg(target_arch = "wasm32")]
8pub use wasm_timer::SystemTime;
9
10#[cfg_attr(feature = "fuzzing", derive(fuzzcheck::DefaultMutator))]
24#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Copy)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
27pub struct Timestamp(u64);
28
29impl Timestamp {
30 pub const ZERO: Self = Self(0);
31
32 #[inline(always)]
33 pub fn new(nanos_from_unix_epoch: u64) -> Self {
34 Self(nanos_from_unix_epoch)
35 }
36
37 #[inline(always)]
38 pub fn global_now() -> Self {
39 Self::new(crate::monotonic_to_time(None))
40 }
41
42 pub fn checked_sub(self, rhs: Timestamp) -> Option<Duration> {
43 self.0.checked_sub(rhs.0).map(Duration::from_nanos)
44 }
45
46 pub fn checked_add(self, other: u64) -> Option<Timestamp> {
47 self.0.checked_add(other).map(Timestamp)
48 }
49}
50
51impl From<Timestamp> for u64 {
52 fn from(t: Timestamp) -> Self {
53 t.0
54 }
55}
56
57impl From<Timestamp> for SystemTime {
58 fn from(value: Timestamp) -> Self {
59 Self::UNIX_EPOCH + Duration::from_nanos(value.into())
60 }
61}
62
63impl std::ops::Add for Timestamp {
64 type Output = Timestamp;
65 #[inline]
66 fn add(self, other: Timestamp) -> Timestamp {
67 Timestamp(self.0 + other.0)
68 }
69}
70
71impl std::ops::Add<u64> for Timestamp {
72 type Output = Timestamp;
73 #[inline]
74 fn add(self, other: u64) -> Timestamp {
75 Timestamp(self.0 + other)
76 }
77}
78
79impl std::ops::Add<Duration> for Timestamp {
80 type Output = Timestamp;
81 #[inline]
82 fn add(self, other: Duration) -> Timestamp {
83 Timestamp(self.0 + other.as_nanos() as u64)
84 }
85}