midnight_base_crypto/
time.rs1use crate::fab::Aligned;
16use crate::fab::Alignment;
17use crate::fab::Value;
18use crate::fab::ValueAtom;
19use serialize::{Deserializable, Serializable, Tagged, tag_enforcement_test};
20use std::ops::Add;
21use std::ops::AddAssign;
22use std::ops::Sub;
23
24#[derive(
25 Clone,
26 Copy,
27 Debug,
28 PartialEq,
29 Eq,
30 PartialOrd,
31 Ord,
32 Hash,
33 Default,
34 Serializable,
35 serde::Serialize,
36 serde::Deserialize,
37)]
38#[tag = "timestamp"]
39pub struct Timestamp(u64);
41tag_enforcement_test!(Timestamp);
42
43impl Timestamp {
44 pub const MAX: Timestamp = Timestamp(u64::MAX);
46
47 pub const fn from_secs(s: u64) -> Self {
49 Timestamp(s)
50 }
51
52 pub fn to_secs(self) -> u64 {
54 self.0
55 }
56}
57
58impl rand::distributions::Distribution<Timestamp> for rand::distributions::Standard {
59 fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Timestamp {
60 Timestamp(rng.r#gen())
61 }
62}
63
64impl Aligned for Timestamp {
65 fn alignment() -> Alignment {
66 u64::alignment()
67 }
68}
69
70impl From<Timestamp> for ValueAtom {
71 fn from(timestamp: Timestamp) -> ValueAtom {
72 ValueAtom::from(timestamp.0).normalize()
73 }
74}
75
76impl From<Timestamp> for Value {
77 fn from(val: Timestamp) -> Value {
78 Value(vec![val.into()])
79 }
80}
81
82impl Sub<Self> for Timestamp {
83 type Output = Duration;
84
85 fn sub(self, rhs: Self) -> Self::Output {
86 Duration(self.0 as i128 - rhs.0 as i128)
87 }
88}
89
90impl AddAssign<Duration> for Timestamp {
91 fn add_assign(&mut self, rhs: Duration) {
92 *self = *self + rhs;
93 }
94}
95
96impl Add<Duration> for Timestamp {
97 type Output = Timestamp;
98
99 fn add(self, rhs: Duration) -> Self::Output {
100 if rhs.0 >= 0 {
101 let result = self.0.saturating_add(rhs.0 as u64);
102 Timestamp(result)
103 } else {
104 let abs_duration: u64 = rhs
105 .0
106 .checked_abs()
107 .and_then(|val| u64::try_from(val).ok())
108 .unwrap_or(u64::MAX);
109 Timestamp(self.0.saturating_sub(abs_duration))
110 }
111 }
112}
113
114impl Sub<Duration> for Timestamp {
115 type Output = Timestamp;
116
117 fn sub(self, rhs: Duration) -> Self::Output {
118 if rhs.0 >= 0 {
119 let result = self.0.saturating_sub(rhs.0 as u64);
120 Timestamp(result)
121 } else {
122 let abs_duration: u64 = rhs
123 .0
124 .checked_abs()
125 .and_then(|val| u64::try_from(val).ok())
126 .unwrap_or(u64::MAX);
127 Timestamp(self.0.saturating_add(abs_duration))
128 }
129 }
130}
131
132#[derive(
133 Clone,
134 Copy,
135 Debug,
136 PartialEq,
137 Eq,
138 PartialOrd,
139 Ord,
140 Serializable,
141 Hash,
142 Default,
143 serde::Serialize,
144 serde::Deserialize,
145)]
146#[serde(transparent)]
147#[tag = "duration"]
148pub struct Duration(i128);
150tag_enforcement_test!(Duration);
151
152impl Duration {
153 pub const fn from_secs(s: i128) -> Self {
155 Duration(s)
156 }
157
158 pub const fn from_hours(h: i128) -> Self {
160 Duration::from_secs(h * 60 * 60)
161 }
162
163 pub fn as_seconds(self) -> i128 {
165 self.0
166 }
167}
168
169impl Add<Duration> for Duration {
170 type Output = Self;
171
172 fn add(self, rhs: Self) -> Self::Output {
173 Duration(self.0.saturating_add(rhs.0))
174 }
175}
176
177impl Sub<Self> for Duration {
178 type Output = Self;
179
180 fn sub(self, rhs: Self) -> Self::Output {
181 Duration(self.0.saturating_sub(rhs.0))
182 }
183}