packet_strata/
timestamp.rs1use chrono::{DateTime};
2use serde::{Deserialize, Serialize};
3use std::{
4 fmt,
5 ops::{Add, Div, Mul, Sub},
6};
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
9pub struct Timestamp(pub u64); impl Timestamp {
12 pub const ZERO: Self = Timestamp(0);
13
14 #[inline]
15 pub fn from_nanos(nanos: u64) -> Self {
16 Self(nanos)
17 }
18
19 #[inline]
20 pub fn as_nanos(&self) -> u64 {
21 self.0
22 }
23
24 pub fn as_secs_f64(&self) -> f64 {
25 self.0 as f64 / 1_000_000_000.0
26 }
27}
28
29impl fmt::Display for Timestamp {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 if let Some(date_time) = DateTime::from_timestamp(
32 (self.0 / 1_000_000_000) as i64,
33 (self.0 % 1_000_000_000) as u32,
34 ) {
35 if !f.alternate() {
36 return write!(f, "{}", date_time.format("%Y-%m-%d %H:%M:%S%.6f UTC"));
37 }
38 }
39
40 write!(
41 f,
42 "{}.{:09}",
43 self.0 / 1_000_000_000,
44 self.0 % 1_000_000_000
45 )
46 }
47}
48
49#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
50pub struct Interval(pub i64); impl Interval {
53 pub const ZERO: Self = Interval(0);
54
55 #[inline]
56 pub fn from_nanos(nanos: i64) -> Self {
57 Self(nanos)
58 }
59
60 #[inline]
61 pub fn as_nanos(&self) -> i64 {
62 self.0
63 }
64
65 pub fn as_secs_f64(&self) -> f64 {
66 self.0 as f64 / 1_000_000_000.0
67 }
68
69 pub fn abs(&self) -> Self {
70 Self(self.0.abs())
71 }
72}
73
74impl fmt::Display for Interval {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 let total_nanos = self.0.abs();
77 let secs = total_nanos / 1_000_000_000;
78 let nanos = total_nanos % 1_000_000_000;
79 let sign = if self.0 < 0 { "-" } else { "" };
80 write!(f, "{}{}.{:09}", sign, secs, nanos)
81 }
82}
83
84impl Add<Interval> for Timestamp {
87 type Output = Timestamp;
88 #[inline]
89 fn add(self, rhs: Interval) -> Self::Output {
90 Timestamp(self.0.saturating_add_signed(rhs.0))
91 }
92}
93
94impl Sub<Interval> for Timestamp {
95 type Output = Timestamp;
96 #[inline]
97 fn sub(self, rhs: Interval) -> Self::Output {
98 Timestamp(self.0.saturating_sub_signed(rhs.0))
99 }
100}
101
102impl Sub for Timestamp {
103 type Output = Interval;
104 #[inline]
105 fn sub(self, rhs: Self) -> Self::Output {
106 if self.0 >= rhs.0 {
107 Interval((self.0 - rhs.0) as i64)
108 } else {
109 Interval(-((rhs.0 - self.0) as i64))
110 }
111 }
112}
113
114impl Add for Interval {
117 type Output = Interval;
118 #[inline]
119 fn add(self, rhs: Self) -> Self::Output {
120 Interval(self.0.saturating_add(rhs.0))
121 }
122}
123
124impl Sub for Interval {
125 type Output = Interval;
126 #[inline]
127 fn sub(self, rhs: Self) -> Self::Output {
128 Interval(self.0.saturating_sub(rhs.0))
129 }
130}
131
132impl Mul<f64> for Interval {
133 type Output = Interval;
134 #[inline]
135 fn mul(self, rhs: f64) -> Self::Output {
136 Interval((self.0 as f64 * rhs) as i64)
137 }
138}
139
140impl Div<i64> for Interval {
141 type Output = Interval;
142 #[inline]
143 fn div(self, rhs: i64) -> Self::Output {
144 Interval(self.0 / rhs)
145 }
146}
147
148impl Add<Timestamp> for Interval {
149 type Output = Timestamp;
150 #[inline]
151 fn add(self, rhs: Timestamp) -> Self::Output {
152 rhs + self
153 }
154}