1use std::ffi::c_longlong;
2use std::ops::{Add, Sub};
3use std::time::Duration;
4
5#[repr(transparent)]
7#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
8pub struct Timestamp(u64);
9
10impl Timestamp {
11 pub const ZERO: Self = Self(0);
13
14 #[must_use]
16 pub const fn from_millis(ts: u64) -> Self {
17 Self(ts)
18 }
19
20 #[must_use]
22 pub const fn as_millis(self) -> u64 {
23 self.0
24 }
25
26 pub(crate) fn as_native(self) -> c_longlong {
27 self.0
28 .try_into()
29 .expect("Could not convert u64 timestamp into native timestamp")
30 }
31}
32
33impl Sub for Timestamp {
34 type Output = Duration;
35
36 fn sub(self, rhs: Self) -> Self::Output {
37 let delta_ms = self.0 - rhs.0;
38 Duration::from_millis(delta_ms)
39 }
40}
41
42impl Add<Duration> for Timestamp {
43 type Output = Self;
44
45 fn add(self, rhs: Duration) -> Self::Output {
46 let rhs_u64: u64 = rhs
47 .as_millis()
48 .try_into()
49 .expect("Overflow when adding duration to timestamp");
50
51 Self(self.0 + rhs_u64)
52 }
53}
54
55#[cfg(test)]
56mod test {
57 use super::Timestamp;
58 use std::time::Duration;
59
60 #[test]
61 fn timestamps_work() {
62 let a = Timestamp::from_millis(0);
63 let b = Timestamp::from_millis(100);
64 let c = b + Duration::from_millis(100);
65
66 assert_eq!((b - a).as_millis(), 100);
67 assert_eq!(c.as_millis(), 200);
68 }
69}