1 | use super::MAX_SAFE_MILLIS_DURATION; |
2 | use crate::time::{Clock, Duration, Instant}; |
3 | |
4 | /// A structure which handles conversion from Instants to `u64` timestamps. |
5 | #[derive (Debug)] |
6 | pub(crate) struct TimeSource { |
7 | start_time: Instant, |
8 | } |
9 | |
10 | impl TimeSource { |
11 | pub(crate) fn new(clock: &Clock) -> Self { |
12 | Self { |
13 | start_time: clock.now(), |
14 | } |
15 | } |
16 | |
17 | pub(crate) fn deadline_to_tick(&self, t: Instant) -> u64 { |
18 | // Round up to the end of a ms |
19 | self.instant_to_tick(t + Duration::from_nanos(999_999)) |
20 | } |
21 | |
22 | pub(crate) fn instant_to_tick(&self, t: Instant) -> u64 { |
23 | // round up |
24 | let dur: Duration = t |
25 | .checked_duration_since(self.start_time) |
26 | .unwrap_or_else(|| Duration::from_secs(0)); |
27 | let ms = dur.as_millis(); |
28 | |
29 | ms.try_into().unwrap_or(MAX_SAFE_MILLIS_DURATION) |
30 | } |
31 | |
32 | pub(crate) fn tick_to_duration(&self, t: u64) -> Duration { |
33 | Duration::from_millis(t) |
34 | } |
35 | |
36 | pub(crate) fn now(&self, clock: &Clock) -> u64 { |
37 | self.instant_to_tick(clock.now()) |
38 | } |
39 | } |
40 | |