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(self, now: Self) -> Duration {
42 Duration::from_millis(now.0.saturating_sub(self.0))
43 }
44
45 pub fn is_fresh_at(self, now: Self, max_age: Duration) -> bool {
46 self.age_at(now) <= max_age
47 }
48}
49
50impl From<u64> for OrbitEpoch {
51 fn from(value: u64) -> Self {
52 Self::from_unix_ms(value)
53 }
54}
55
56impl From<OrbitEpoch> for u64 {
57 fn from(value: OrbitEpoch) -> Self {
58 value.as_unix_ms()
59 }
60}
61
62impl std::fmt::Display for OrbitEpoch {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 write!(f, "{}", self.0)
65 }
66}