Line | Count | Source |
1 | | // Copyright Istio Authors |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | use std::time::{Instant, SystemTime}; |
16 | | |
17 | | #[derive(Clone)] |
18 | | pub struct Converter { |
19 | | now: Instant, |
20 | | sys_now: SystemTime, |
21 | | } |
22 | | |
23 | | impl Converter { |
24 | 0 | pub fn new() -> Self { |
25 | 0 | Self::new_at(SystemTime::now()) |
26 | 0 | } |
27 | | |
28 | 0 | pub fn new_at(sys_now: SystemTime) -> Self { |
29 | 0 | Self { |
30 | 0 | sys_now, |
31 | 0 | now: Instant::now(), |
32 | 0 | } |
33 | 0 | } |
34 | | |
35 | 0 | pub fn system_time_to_instant(&self, t: SystemTime) -> Option<Instant> { |
36 | 0 | match t.duration_since(self.sys_now) { |
37 | 0 | Ok(d) => Some(self.now + d), |
38 | 0 | Err(_) => match self.sys_now.duration_since(t) { |
39 | 0 | Ok(d) => self.now.checked_sub(d), |
40 | 0 | Err(_) => panic!("time both before and after"), |
41 | | }, |
42 | | } |
43 | 0 | } |
44 | | |
45 | 0 | pub fn instant_to_system_time(&self, t: Instant) -> Option<SystemTime> { |
46 | 0 | if t > self.now { |
47 | 0 | self.sys_now |
48 | 0 | .checked_add(t.saturating_duration_since(self.now)) |
49 | | } else { |
50 | 0 | self.sys_now |
51 | 0 | .checked_sub(self.now.saturating_duration_since(t)) |
52 | | } |
53 | 0 | } |
54 | | |
55 | 0 | pub fn elapsed_nanos(&self, now: Instant) -> u128 { |
56 | 0 | now.duration_since(self.now).as_nanos() |
57 | 0 | } |
58 | | |
59 | 0 | pub fn subsec_nanos(&self) -> u32 { |
60 | 0 | self.sys_now |
61 | 0 | .duration_since(SystemTime::UNIX_EPOCH) |
62 | 0 | .unwrap() |
63 | 0 | .subsec_nanos() |
64 | 0 | } |
65 | | } |
66 | | |
67 | | impl Default for Converter { |
68 | 0 | fn default() -> Self { |
69 | 0 | Self::new() |
70 | 0 | } |
71 | | } |
72 | | |
73 | | #[cfg(test)] |
74 | | mod tests { |
75 | | use std::time::{Duration, Instant}; |
76 | | |
77 | | #[test] |
78 | | fn test_converter() { |
79 | | const DELAY: Duration = Duration::from_secs(1); |
80 | | let conv = super::Converter::new(); |
81 | | let now = Instant::now(); |
82 | | let sys_now = conv.instant_to_system_time(now).unwrap(); |
83 | | let later = conv.system_time_to_instant(sys_now + DELAY); |
84 | | assert_eq!(later, Some(now + DELAY)); |
85 | | } |
86 | | } |