1use std::time::{Duration, SystemTime, UNIX_EPOCH};
10
11#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
14#[repr(transparent)]
15pub struct OrbitEpoch(u64);
16
17impl OrbitEpoch {
18 pub const ZERO: Self = Self(0);
19
20 pub fn now() -> Self {
21 Self::from_system_time(SystemTime::now())
22 }
23
24 pub fn from_system_time(time: SystemTime) -> Self {
25 let millis = time
26 .duration_since(UNIX_EPOCH)
27 .unwrap_or_default()
28 .as_millis()
29 .min(u128::from(u64::MAX)) as u64;
30 Self(millis)
31 }
32
33 pub const fn from_unix_ms(epoch_ms: u64) -> Self {
34 Self(epoch_ms)
35 }
36
37 pub const fn as_unix_ms(self) -> u64 {
38 self.0
39 }
40
41 pub fn age_at(
42 self,
43 now: Self
44 ) -> Duration {
45 Duration::from_millis(now.0.saturating_sub(self.0))
46 }
47
48 pub fn is_fresh_at(
49 self,
50 now: Self,
51 max_age: Duration
52 ) -> bool {
53 self.age_at(now) <= max_age
54 }
55}
56
57impl From<u64> for OrbitEpoch {
58 fn from(value: u64) -> Self {
59 Self::from_unix_ms(value)
60 }
61}
62
63impl From<OrbitEpoch> for u64 {
64 fn from(value: OrbitEpoch) -> Self {
65 value.as_unix_ms()
66 }
67}
68
69impl std::fmt::Display for OrbitEpoch {
70 fn fmt(
71 &self,
72 f: &mut std::fmt::Formatter<'_>
73 ) -> std::fmt::Result {
74 write!(f, "{}", self.0)
75 }
76}