| 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 | |