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.saturating_duration_since(self.start_time); |
25 | let ms = dur |
26 | .as_millis() |
27 | .try_into() |
28 | .unwrap_or(MAX_SAFE_MILLIS_DURATION); |
29 | ms.min(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 | #[cfg (test)] |
41 | #[allow (dead_code)] |
42 | pub(super) fn start_time(&self) -> Instant { |
43 | self.start_time |
44 | } |
45 | } |
46 | |