From 0b965401c53f3da9f4074cfe96cb77bbde272c84 Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Fri, 9 Sep 2022 19:36:35 +0200 Subject: [PATCH] clock: new module, system and fixed time options --- src/protocol/clock.rs | 101 ++++++++++++++++++++++++++++++++++++++++++ src/protocol/mod.rs | 1 + 2 files changed, 102 insertions(+) create mode 100644 src/protocol/clock.rs diff --git a/src/protocol/clock.rs b/src/protocol/clock.rs new file mode 100644 index 000000000..5fc6c84eb --- /dev/null +++ b/src/protocol/clock.rs @@ -0,0 +1,101 @@ +use std::{ + cell::RefCell, + convert::TryInto, + ops::Div, + time::{Duration, SystemTime}, +}; + +pub trait Time: Sized + Div + Into + TryInto { + fn now() -> Self; + fn after(period: &Duration) -> Self; + + fn after_sec(period: u64) -> Self { + Self::after(&Duration::new(period, 0)) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct UnixTime(pub Duration); + +pub enum ClockType { + SystemTime, + FixedTime, +} + +#[cfg(not(test))] +pub type DefaultTime = UnixTime<{ ClockType::SystemTime as usize }>; + +#[cfg(test)] +pub type DefaultTime = UnixTime<{ ClockType::FixedTime as usize }>; + +pub type CurrentTime = UnixTime<{ ClockType::SystemTime as usize }>; + +impl Time for UnixTime<{ ClockType::SystemTime as usize }> { + fn now() -> Self { + Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()) + } + + fn after(period: &Duration) -> Self { + Self( + SystemTime::now() + .checked_add(*period) + .unwrap() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(), + ) + } +} + +thread_local!(static FIXED_TIME: RefCell = RefCell::new(Duration::ZERO)); + +impl Time for UnixTime<{ ClockType::FixedTime as usize }> { + fn now() -> Self { + let mut now: Duration = Duration::default(); + FIXED_TIME.with(|time| { + now = *time.borrow(); + }); + + Self(now) + } + + fn after(period: &Duration) -> Self { + let mut now: Duration = Duration::default(); + FIXED_TIME.with(|time| { + now = *time.borrow(); + }); + + Self(now.checked_add(*period).unwrap()) + } +} + +impl UnixTime<{ ClockType::FixedTime as usize }> { + pub fn set_time(new_time: &Duration) { + FIXED_TIME.with(|time| { + *time.borrow_mut() = *new_time; + }); + } + pub fn reset_time() { + Self::set_time(&Duration::ZERO) + } +} + +impl Div for UnixTime<{ T }> { + type Output = u128; + fn div(self, rhs: Self) -> Self::Output { + self.0.as_nanos() / rhs.0.as_nanos() + } +} + +impl Into for UnixTime<{ T }> { + fn into(self) -> u64 { + self.0.as_secs() + } +} + +impl TryInto for UnixTime<{ T }> { + type Error = >::Error; + + fn try_into(self) -> Result { + self.0.as_secs().try_into() + } +} diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 99cfd91e4..fcb28b3b2 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -1,2 +1,3 @@ +pub mod clock; pub mod common; pub mod utils;