1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use std::convert::{TryFrom, TryInto};
use std::ops;
use std::time;
use std::time::Duration;
use tc_error::*;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct NetworkTime {
nanos: u64,
}
impl NetworkTime {
pub fn now() -> NetworkTime {
NetworkTime::from_nanos(
time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.unwrap()
.as_nanos() as u64,
)
}
pub fn as_nanos(&self) -> u64 {
self.nanos
}
pub fn from_nanos(nanos: u64) -> NetworkTime {
NetworkTime { nanos }
}
}
impl ops::Add<time::Duration> for NetworkTime {
type Output = Self;
fn add(self, other: time::Duration) -> Self {
NetworkTime {
nanos: self.nanos + other.as_nanos() as u64,
}
}
}
impl TryFrom<time::SystemTime> for NetworkTime {
type Error = TCError;
fn try_from(st: time::SystemTime) -> TCResult<NetworkTime> {
let st = st
.duration_since(time::UNIX_EPOCH)
.map_err(|e| TCError::bad_request("invalid timestamp", e))?;
let nanos: u64 = st
.as_nanos()
.try_into()
.map_err(|e| TCError::bad_request("invalid timestamp", e))?;
Ok(NetworkTime::from_nanos(nanos))
}
}
impl From<NetworkTime> for time::SystemTime {
fn from(nt: NetworkTime) -> Self {
time::UNIX_EPOCH + Duration::from_nanos(nt.nanos as u64)
}
}