From cdbe0d12dea35e64b001088d545a466104ffd899 Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Tue, 13 Sep 2022 00:56:05 +0200 Subject: [PATCH 1/7] clock: add clock period modules --- src/protocol/clock/clockperiod.rs | 92 +++++++++++++++++++++++++ src/protocol/clock/mod.rs | 2 + src/protocol/clock/period.rs | 108 ++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 src/protocol/clock/clockperiod.rs create mode 100644 src/protocol/clock/period.rs diff --git a/src/protocol/clock/clockperiod.rs b/src/protocol/clock/clockperiod.rs new file mode 100644 index 000000000..5f71a414f --- /dev/null +++ b/src/protocol/clock/clockperiod.rs @@ -0,0 +1,92 @@ +use std::num::TryFromIntError; +use std::time::Duration; + +use super::clock::{ClockType, StoppedClock, TimeNow, WorkingClock}; +use super::period::{self, Periods}; + +pub trait ClockPeriods: Sized +where + T: TimeNow, +{ + fn now(length: &period::PeriodLength) -> Option> { + match T::now().as_nanos().checked_div((*length).as_nanos()) { + None => None, + Some(count) => Some(match period::PeriodCount::try_from(count) { + Err(error) => Err(error), + Ok(count) => Ok(period::SinceUnixEpochPeriods::new(&length, &count)), + }), + } + } + + fn now_add( + length: &period::PeriodLength, + add_time: &Duration, + ) -> Option> { + match T::add(add_time) { + None => None, + Some(time) => match time.as_nanos().checked_div(length.as_nanos()) { + None => None, + Some(count) => Some(match period::PeriodCount::try_from(count) { + Err(error) => Err(error), + Ok(count) => Ok(period::SinceUnixEpochPeriods::new(&length, &count)), + }), + }, + } + } + fn now_sub( + length: &period::PeriodLength, + sub_time: &Duration, + ) -> Option> { + match T::sub(sub_time) { + None => None, + Some(time) => match time.as_nanos().checked_div(length.as_nanos()) { + None => None, + Some(count) => Some(match period::PeriodCount::try_from(count) { + Err(error) => Err(error), + Ok(count) => Ok(period::SinceUnixEpochPeriods::new(&length, &count)), + }), + }, + } + } +} + +#[derive(Debug)] +pub struct PeriodClock {} + +pub type ClockPeriodWorking = PeriodClock<{ ClockType::WorkingClock as usize }>; + +pub type StoppedPeriodClock = PeriodClock<{ ClockType::StoppedClock as usize }>; + +impl ClockPeriods for ClockPeriodWorking {} + +impl ClockPeriods for StoppedPeriodClock {} + +#[cfg(not(test))] +pub type DefaultPeriodClock = ClockPeriodWorking; + +#[cfg(test)] +pub type DefaultPeriodClock = StoppedPeriodClock; + +#[cfg(test)] +mod tests { + use std::time::Duration; + + use crate::protocol::clock::clock::{DefaultClock, SinceUnixEpoch, StoppedTime}; + use crate::protocol::clock::clockperiod::{ClockPeriods, DefaultPeriodClock}; + use crate::protocol::clock::period::Period; + + #[test] + fn it_should_get_the_current_period() { + assert_eq!( + DefaultPeriodClock::now(&Duration::from_secs(2)).unwrap().unwrap(), + Period::from_sec(2, 0) + ); + + DefaultClock::local_set(&SinceUnixEpoch::from_secs(12387687123)); + + assert_eq!( + DefaultPeriodClock::now(&Duration::from_secs(2)).unwrap().unwrap(), + Period::from_sec(2, 6193843561) + ); + } +} diff --git a/src/protocol/clock/mod.rs b/src/protocol/clock/mod.rs index 159730d2b..e60fb403b 100644 --- a/src/protocol/clock/mod.rs +++ b/src/protocol/clock/mod.rs @@ -1 +1,3 @@ pub mod clock; +pub mod clockperiod; +pub mod period; diff --git a/src/protocol/clock/period.rs b/src/protocol/clock/period.rs new file mode 100644 index 000000000..4077aeb4a --- /dev/null +++ b/src/protocol/clock/period.rs @@ -0,0 +1,108 @@ +use std::num::{IntErrorKind, TryFromIntError}; +use std::time::Duration; + +pub type PeriodLength = Duration; +pub type PeriodCount = u64; +pub type PeriodTotalTime = Duration; + +pub trait Periods: Sized + Default { + fn new(length: &PeriodLength, count: &PeriodCount) -> Self; + + fn add_count(&self, add: PeriodCount) -> Result; + fn sub_count(&self, sub: PeriodCount) -> Result; +} + +pub trait PeriodsTotals: Periods { + fn total_time(&self) -> Result, TryFromIntError>; + fn total_time_end(&self) -> Result, TryFromIntError>; +} + +#[derive(Debug, Default, Hash, PartialEq)] +pub struct Period { + pub length: PeriodLength, + pub count: PeriodCount, +} + +pub type SinceUnixEpochPeriods = Period; + +impl Period { + pub const fn from_sec(length: u64, count: u64) -> Self { + Self { + length: Duration::from_secs(length), + count: count, + } + } +} + +impl Periods for Period { + fn new(length: &PeriodLength, count: &PeriodCount) -> Self { + Self { + length: *length, + count: *count, + } + } + + fn add_count(&self, add: PeriodCount) -> Result { + match self.count.checked_add(add) { + None => Err(IntErrorKind::PosOverflow), + Some(count) => Ok(Self { + length: self.length, + count: count, + }), + } + } + + fn sub_count(&self, sub: PeriodCount) -> Result { + match self.count.checked_sub(sub) { + None => Err(IntErrorKind::NegOverflow), + Some(count) => Ok(Self { + length: self.length, + count: count, + }), + } + } +} + +impl PeriodsTotals for Period { + fn total_time(&self) -> Result, TryFromIntError> { + match u32::try_from(self.count) { + Err(error) => Err(error), + Ok(count) => Ok(self.length.checked_mul(count)), + } + } + + fn total_time_end(&self) -> Result, TryFromIntError> { + match u32::try_from(self.count) { + Err(e) => Err(e), + Ok(count) => match count.checked_add(1) { + None => Ok(None), + Some(count) => match self.length.checked_mul(count) { + None => Ok(None), + Some(time) => Ok(Some(time)), + }, + }, + } + } +} + +#[cfg(test)] +mod test { + + use std::time::Duration; + + use crate::protocol::clock::period::{Period, PeriodsTotals}; + + #[test] + fn it_should_get_the_total_time_of_a_period() { + assert_eq!(Period::default().total_time().unwrap().unwrap(), Duration::ZERO); + + assert_eq!( + Period::from_sec(12, 12).total_time().unwrap().unwrap(), + Duration::from_secs(144) + ); + assert_eq!( + Period::from_sec(12, 12).total_time_end().unwrap().unwrap(), + Duration::from_secs(156) + ); + } +} From 58fe5b2150fac93a7f766fb30550643526fe476a Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 14 Sep 2022 20:01:11 +0200 Subject: [PATCH 2/7] refactor: Clippy suggestions --- src/protocol/clock/clockperiod.rs | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/protocol/clock/clockperiod.rs b/src/protocol/clock/clockperiod.rs index 5f71a414f..8642385b7 100644 --- a/src/protocol/clock/clockperiod.rs +++ b/src/protocol/clock/clockperiod.rs @@ -9,13 +9,11 @@ where T: TimeNow, { fn now(length: &period::PeriodLength) -> Option> { - match T::now().as_nanos().checked_div((*length).as_nanos()) { - None => None, - Some(count) => Some(match period::PeriodCount::try_from(count) { + T::now().as_nanos().checked_div(length.as_nanos()) + .map(|count| match period::PeriodCount::try_from(count) { Err(error) => Err(error), - Ok(count) => Ok(period::SinceUnixEpochPeriods::new(&length, &count)), - }), - } + Ok(count) => Ok(period::SinceUnixEpochPeriods::new(length, &count)), + }) } fn now_add( @@ -24,13 +22,11 @@ where ) -> Option> { match T::add(add_time) { None => None, - Some(time) => match time.as_nanos().checked_div(length.as_nanos()) { - None => None, - Some(count) => Some(match period::PeriodCount::try_from(count) { + Some(time) => time.as_nanos().checked_div(length.as_nanos()) + .map(|count| match period::PeriodCount::try_from(count) { Err(error) => Err(error), - Ok(count) => Ok(period::SinceUnixEpochPeriods::new(&length, &count)), + Ok(count) => Ok(period::SinceUnixEpochPeriods::new(length, &count)), }), - }, } } fn now_sub( @@ -39,13 +35,11 @@ where ) -> Option> { match T::sub(sub_time) { None => None, - Some(time) => match time.as_nanos().checked_div(length.as_nanos()) { - None => None, - Some(count) => Some(match period::PeriodCount::try_from(count) { + Some(time) => time.as_nanos().checked_div(length.as_nanos()) + .map(|count| match period::PeriodCount::try_from(count) { Err(error) => Err(error), - Ok(count) => Ok(period::SinceUnixEpochPeriods::new(&length, &count)), + Ok(count) => Ok(period::SinceUnixEpochPeriods::new(length, &count)), }), - }, } } } From 7f078b8179e299a6b21a0a0960f3d82378358969 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 14 Sep 2022 20:26:20 +0200 Subject: [PATCH 3/7] refactor: renamed `SinceUnixEpoch` to `DurationSinceUnixEpoch` to be more descriptive --- src/databases/sqlite.rs | 6 ++--- src/protocol/clock/clock.rs | 38 +++++++++++++++---------------- src/protocol/clock/clockperiod.rs | 4 ++-- src/protocol/utils.rs | 4 ++-- src/tracker/key.rs | 6 ++--- src/tracker/peer.rs | 4 ++-- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/databases/sqlite.rs b/src/databases/sqlite.rs index ff080306d..a329b6bfc 100644 --- a/src/databases/sqlite.rs +++ b/src/databases/sqlite.rs @@ -7,7 +7,7 @@ use r2d2_sqlite::SqliteConnectionManager; use crate::databases::database; use crate::databases::database::{Database, Error}; -use crate::protocol::clock::clock::SinceUnixEpoch; +use crate::protocol::clock::clock::DurationSinceUnixEpoch; use crate::tracker::key::AuthKey; use crate::InfoHash; @@ -86,7 +86,7 @@ impl Database for SqliteDatabase { Ok(AuthKey { key, - valid_until: Some(SinceUnixEpoch::from_secs(valid_until as u64)), + valid_until: Some(DurationSinceUnixEpoch::from_secs(valid_until as u64)), }) })?; @@ -193,7 +193,7 @@ impl Database for SqliteDatabase { Ok(AuthKey { key, - valid_until: Some(SinceUnixEpoch::from_secs(valid_until_i64 as u64)), + valid_until: Some(DurationSinceUnixEpoch::from_secs(valid_until_i64 as u64)), }) } else { Err(database::Error::QueryReturnedNoRows) diff --git a/src/protocol/clock/clock.rs b/src/protocol/clock/clock.rs index db59170b3..538edcfed 100644 --- a/src/protocol/clock/clock.rs +++ b/src/protocol/clock/clock.rs @@ -1,7 +1,7 @@ use std::num::IntErrorKind; pub use std::time::Duration; -pub type SinceUnixEpoch = Duration; +pub type DurationSinceUnixEpoch = Duration; #[derive(Debug)] pub enum ClockType { @@ -22,14 +22,14 @@ pub type DefaultClock = WorkingClock; pub type DefaultClock = StoppedClock; pub trait Time: Sized { - fn now() -> SinceUnixEpoch; + fn now() -> DurationSinceUnixEpoch; } pub trait TimeNow: Time { - fn add(add_time: &Duration) -> Option { + fn add(add_time: &Duration) -> Option { Self::now().checked_add(*add_time) } - fn sub(sub_time: &Duration) -> Option { + fn sub(sub_time: &Duration) -> Option { Self::now().checked_sub(*sub_time) } } @@ -57,10 +57,10 @@ mod tests { mod working_clock { use std::time::SystemTime; - use super::{SinceUnixEpoch, Time, TimeNow, WorkingClock}; + use super::{DurationSinceUnixEpoch, Time, TimeNow, WorkingClock}; impl Time for WorkingClock { - fn now() -> SinceUnixEpoch { + fn now() -> DurationSinceUnixEpoch { SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap() } } @@ -69,9 +69,9 @@ mod working_clock { } pub trait StoppedTime: TimeNow { - fn local_set(unix_time: &SinceUnixEpoch); + fn local_set(unix_time: &DurationSinceUnixEpoch); fn local_set_to_unix_epoch() { - Self::local_set(&SinceUnixEpoch::ZERO) + Self::local_set(&DurationSinceUnixEpoch::ZERO) } fn local_set_to_app_start_time(); fn local_set_to_system_time_now(); @@ -84,10 +84,10 @@ mod stopped_clock { use std::num::IntErrorKind; use std::time::Duration; - use super::{SinceUnixEpoch, StoppedClock, StoppedTime, Time, TimeNow}; + use super::{DurationSinceUnixEpoch, StoppedClock, StoppedTime, Time, TimeNow}; impl Time for StoppedClock { - fn now() -> SinceUnixEpoch { + fn now() -> DurationSinceUnixEpoch { detail::FIXED_TIME.with(|time| { return *time.borrow(); }) @@ -97,7 +97,7 @@ mod stopped_clock { impl TimeNow for StoppedClock {} impl StoppedTime for StoppedClock { - fn local_set(unix_time: &SinceUnixEpoch) { + fn local_set(unix_time: &DurationSinceUnixEpoch) { detail::FIXED_TIME.with(|time| { *time.borrow_mut() = *unix_time; }) @@ -147,11 +147,11 @@ mod stopped_clock { use std::thread; use std::time::Duration; - use crate::protocol::clock::clock::{SinceUnixEpoch, StoppedClock, StoppedTime, Time, TimeNow, WorkingClock}; + use crate::protocol::clock::clock::{DurationSinceUnixEpoch, StoppedClock, StoppedTime, Time, TimeNow, WorkingClock}; #[test] fn it_should_default_to_zero_when_testing() { - assert_eq!(StoppedClock::now(), SinceUnixEpoch::ZERO) + assert_eq!(StoppedClock::now(), DurationSinceUnixEpoch::ZERO) } #[test] @@ -206,26 +206,26 @@ mod stopped_clock { use std::cell::RefCell; use std::time::SystemTime; - use crate::protocol::clock::clock::SinceUnixEpoch; + use crate::protocol::clock::clock::DurationSinceUnixEpoch; use crate::static_time; - pub fn get_app_start_time() -> SinceUnixEpoch { + pub fn get_app_start_time() -> DurationSinceUnixEpoch { (*static_time::TIME_AT_APP_START) .duration_since(SystemTime::UNIX_EPOCH) .unwrap() } #[cfg(not(test))] - pub fn get_default_fixed_time() -> SinceUnixEpoch { + pub fn get_default_fixed_time() -> DurationSinceUnixEpoch { get_app_start_time() } #[cfg(test)] - pub fn get_default_fixed_time() -> SinceUnixEpoch { - SinceUnixEpoch::ZERO + pub fn get_default_fixed_time() -> DurationSinceUnixEpoch { + DurationSinceUnixEpoch::ZERO } - thread_local!(pub static FIXED_TIME: RefCell = RefCell::new(get_default_fixed_time())); + thread_local!(pub static FIXED_TIME: RefCell = RefCell::new(get_default_fixed_time())); #[cfg(test)] mod tests { diff --git a/src/protocol/clock/clockperiod.rs b/src/protocol/clock/clockperiod.rs index 8642385b7..128e1a768 100644 --- a/src/protocol/clock/clockperiod.rs +++ b/src/protocol/clock/clockperiod.rs @@ -65,7 +65,7 @@ pub type DefaultPeriodClock = StoppedPeriodClock; mod tests { use std::time::Duration; - use crate::protocol::clock::clock::{DefaultClock, SinceUnixEpoch, StoppedTime}; + use crate::protocol::clock::clock::{DefaultClock, DurationSinceUnixEpoch, StoppedTime}; use crate::protocol::clock::clockperiod::{ClockPeriods, DefaultPeriodClock}; use crate::protocol::clock::period::Period; @@ -76,7 +76,7 @@ mod tests { Period::from_sec(2, 0) ); - DefaultClock::local_set(&SinceUnixEpoch::from_secs(12387687123)); + DefaultClock::local_set(&DurationSinceUnixEpoch::from_secs(12387687123)); assert_eq!( DefaultPeriodClock::now(&Duration::from_secs(2)).unwrap().unwrap(), diff --git a/src/protocol/utils.rs b/src/protocol/utils.rs index f2a68fdb3..127baa4eb 100644 --- a/src/protocol/utils.rs +++ b/src/protocol/utils.rs @@ -2,7 +2,7 @@ use std::net::SocketAddr; use aquatic_udp_protocol::ConnectionId; -use super::clock::clock::{DefaultClock, SinceUnixEpoch, Time}; +use super::clock::clock::{DefaultClock, DurationSinceUnixEpoch, Time}; pub fn get_connection_id(remote_address: &SocketAddr) -> ConnectionId { ConnectionId(((current_time() / 3600) | ((remote_address.port() as u64) << 36)) as i64) @@ -12,6 +12,6 @@ pub fn current_time() -> u64 { DefaultClock::now().as_secs() } -pub fn ser_unix_time_value(unix_time_value: &SinceUnixEpoch, ser: S) -> Result { +pub fn ser_unix_time_value(unix_time_value: &DurationSinceUnixEpoch, ser: S) -> Result { ser.serialize_u64(unix_time_value.as_millis() as u64) } diff --git a/src/tracker/key.rs b/src/tracker/key.rs index 8ba19ab12..76ac21527 100644 --- a/src/tracker/key.rs +++ b/src/tracker/key.rs @@ -6,7 +6,7 @@ use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; use serde::Serialize; -use crate::protocol::clock::clock::{DefaultClock, SinceUnixEpoch, Time, TimeNow}; +use crate::protocol::clock::clock::{DefaultClock, DurationSinceUnixEpoch, Time, TimeNow}; use crate::AUTH_KEY_LENGTH; pub fn generate_auth_key(lifetime: Duration) -> AuthKey { @@ -25,7 +25,7 @@ pub fn generate_auth_key(lifetime: Duration) -> AuthKey { } pub fn verify_auth_key(auth_key: &AuthKey) -> Result<(), Error> { - let current_time: SinceUnixEpoch = DefaultClock::now(); + let current_time: DurationSinceUnixEpoch = DefaultClock::now(); if auth_key.valid_until.is_none() { return Err(Error::KeyInvalid); } @@ -39,7 +39,7 @@ pub fn verify_auth_key(auth_key: &AuthKey) -> Result<(), Error> { #[derive(Serialize, Debug, Eq, PartialEq, Clone)] pub struct AuthKey { pub key: String, - pub valid_until: Option, + pub valid_until: Option, } impl AuthKey { diff --git a/src/tracker/peer.rs b/src/tracker/peer.rs index b37090b8e..b10c97bcc 100644 --- a/src/tracker/peer.rs +++ b/src/tracker/peer.rs @@ -5,7 +5,7 @@ use serde; use serde::Serialize; use crate::http::AnnounceRequest; -use crate::protocol::clock::clock::{DefaultClock, SinceUnixEpoch, Time}; +use crate::protocol::clock::clock::{DefaultClock, DurationSinceUnixEpoch, Time}; use crate::protocol::common::{AnnounceEventDef, NumberOfBytesDef}; use crate::protocol::utils::ser_unix_time_value; use crate::PeerId; @@ -15,7 +15,7 @@ pub struct TorrentPeer { pub peer_id: PeerId, pub peer_addr: SocketAddr, #[serde(serialize_with = "ser_unix_time_value")] - pub updated: SinceUnixEpoch, + pub updated: DurationSinceUnixEpoch, #[serde(with = "NumberOfBytesDef")] pub uploaded: NumberOfBytes, #[serde(with = "NumberOfBytesDef")] From 6e57ef7dfa4b5ab437dc87658e5a14f83e86b353 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 14 Sep 2022 20:42:14 +0200 Subject: [PATCH 4/7] docs: added docs to describe `Period` --- src/protocol/clock/period.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/protocol/clock/period.rs b/src/protocol/clock/period.rs index 4077aeb4a..7ab92a7c3 100644 --- a/src/protocol/clock/period.rs +++ b/src/protocol/clock/period.rs @@ -17,6 +17,8 @@ pub trait PeriodsTotals: Periods { fn total_time_end(&self) -> Result, TryFromIntError>; } +/// A `Period` type with a `length` as `Duration` and a `count` as `u64`, +/// to represent a time duration and how many times that duration will occur or has occurred. #[derive(Debug, Default, Hash, PartialEq)] pub struct Period { pub length: PeriodLength, From 32d3a724ca50aff7dcae33cbac4ffc560e18932e Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 14 Sep 2022 21:02:14 +0200 Subject: [PATCH 5/7] refactor: Clippy recommendation --- src/protocol/clock/period.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/protocol/clock/period.rs b/src/protocol/clock/period.rs index 7ab92a7c3..456604478 100644 --- a/src/protocol/clock/period.rs +++ b/src/protocol/clock/period.rs @@ -31,7 +31,7 @@ impl Period { pub const fn from_sec(length: u64, count: u64) -> Self { Self { length: Duration::from_secs(length), - count: count, + count, } } } @@ -49,7 +49,7 @@ impl Periods for Period { None => Err(IntErrorKind::PosOverflow), Some(count) => Ok(Self { length: self.length, - count: count, + count, }), } } @@ -59,7 +59,7 @@ impl Periods for Period { None => Err(IntErrorKind::NegOverflow), Some(count) => Ok(Self { length: self.length, - count: count, + count, }), } } From 7d3f08c1f901be9c122309fcc5c43033e69ab360 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 14 Sep 2022 21:25:01 +0200 Subject: [PATCH 6/7] refactor: removed unnecessary traits and added docs --- src/protocol/clock/clockperiod.rs | 16 +++--- src/protocol/clock/period.rs | 85 ++++++++++++++----------------- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/src/protocol/clock/clockperiod.rs b/src/protocol/clock/clockperiod.rs index 128e1a768..11c7c3671 100644 --- a/src/protocol/clock/clockperiod.rs +++ b/src/protocol/clock/clockperiod.rs @@ -8,37 +8,37 @@ pub trait ClockPeriods: Sized where T: TimeNow, { - fn now(length: &period::PeriodLength) -> Option> { + fn now(length: &period::PeriodLength) -> Option> { T::now().as_nanos().checked_div(length.as_nanos()) .map(|count| match period::PeriodCount::try_from(count) { Err(error) => Err(error), - Ok(count) => Ok(period::SinceUnixEpochPeriods::new(length, &count)), + Ok(count) => Ok(period::PeriodSinceUnixEpoch::new(length, &count)), }) } fn now_add( length: &period::PeriodLength, add_time: &Duration, - ) -> Option> { + ) -> Option> { match T::add(add_time) { None => None, Some(time) => time.as_nanos().checked_div(length.as_nanos()) .map(|count| match period::PeriodCount::try_from(count) { Err(error) => Err(error), - Ok(count) => Ok(period::SinceUnixEpochPeriods::new(length, &count)), + Ok(count) => Ok(period::PeriodSinceUnixEpoch::new(length, &count)), }), } } fn now_sub( length: &period::PeriodLength, sub_time: &Duration, - ) -> Option> { + ) -> Option> { match T::sub(sub_time) { None => None, Some(time) => time.as_nanos().checked_div(length.as_nanos()) .map(|count| match period::PeriodCount::try_from(count) { Err(error) => Err(error), - Ok(count) => Ok(period::SinceUnixEpochPeriods::new(length, &count)), + Ok(count) => Ok(period::PeriodSinceUnixEpoch::new(length, &count)), }), } } @@ -73,14 +73,14 @@ mod tests { fn it_should_get_the_current_period() { assert_eq!( DefaultPeriodClock::now(&Duration::from_secs(2)).unwrap().unwrap(), - Period::from_sec(2, 0) + Period::from_secs(2, 0) ); DefaultClock::local_set(&DurationSinceUnixEpoch::from_secs(12387687123)); assert_eq!( DefaultPeriodClock::now(&Duration::from_secs(2)).unwrap().unwrap(), - Period::from_sec(2, 6193843561) + Period::from_secs(2, 6193843561) ); } } diff --git a/src/protocol/clock/period.rs b/src/protocol/clock/period.rs index 456604478..0f41a8d98 100644 --- a/src/protocol/clock/period.rs +++ b/src/protocol/clock/period.rs @@ -4,18 +4,7 @@ use std::time::Duration; pub type PeriodLength = Duration; pub type PeriodCount = u64; pub type PeriodTotalTime = Duration; - -pub trait Periods: Sized + Default { - fn new(length: &PeriodLength, count: &PeriodCount) -> Self; - - fn add_count(&self, add: PeriodCount) -> Result; - fn sub_count(&self, sub: PeriodCount) -> Result; -} - -pub trait PeriodsTotals: Periods { - fn total_time(&self) -> Result, TryFromIntError>; - fn total_time_end(&self) -> Result, TryFromIntError>; -} +pub type PeriodSinceUnixEpoch = Period; /// A `Period` type with a `length` as `Duration` and a `count` as `u64`, /// to represent a time duration and how many times that duration will occur or has occurred. @@ -25,55 +14,33 @@ pub struct Period { pub count: PeriodCount, } -pub type SinceUnixEpochPeriods = Period; - impl Period { - pub const fn from_sec(length: u64, count: u64) -> Self { - Self { - length: Duration::from_secs(length), - count, - } - } -} - -impl Periods for Period { - fn new(length: &PeriodLength, count: &PeriodCount) -> Self { + /// Returns a new `Period`. + pub fn new(length: &PeriodLength, count: &PeriodCount) -> Self { Self { length: *length, count: *count, } } - fn add_count(&self, add: PeriodCount) -> Result { - match self.count.checked_add(add) { - None => Err(IntErrorKind::PosOverflow), - Some(count) => Ok(Self { - length: self.length, - count, - }), - } - } - - fn sub_count(&self, sub: PeriodCount) -> Result { - match self.count.checked_sub(sub) { - None => Err(IntErrorKind::NegOverflow), - Some(count) => Ok(Self { - length: self.length, - count, - }), + /// Returns a new `Period` from seconds. + pub const fn from_secs(seconds: u64, count: u64) -> Self { + Self { + length: Duration::from_secs(seconds), + count, } } -} -impl PeriodsTotals for Period { - fn total_time(&self) -> Result, TryFromIntError> { + /// Return `Self.length` * `Self.count` as `Duration`. + pub fn total_time(&self) -> Result, TryFromIntError> { match u32::try_from(self.count) { Err(error) => Err(error), Ok(count) => Ok(self.length.checked_mul(count)), } } - fn total_time_end(&self) -> Result, TryFromIntError> { + /// Return `Self.length` * (`Self.count` + 1) as `Duration`. + pub fn total_time_end(&self) -> Result, TryFromIntError> { match u32::try_from(self.count) { Err(e) => Err(e), Ok(count) => match count.checked_add(1) { @@ -85,6 +52,28 @@ impl PeriodsTotals for Period { }, } } + + /// Increase `Self.count` by `u64`. + pub fn add_count(&self, add: PeriodCount) -> Result { + match self.count.checked_add(add) { + None => Err(IntErrorKind::PosOverflow), + Some(count) => Ok(Self { + length: self.length, + count, + }), + } + } + + /// Decrease `Self.count` by `u64`. + pub fn sub_count(&self, sub: PeriodCount) -> Result { + match self.count.checked_sub(sub) { + None => Err(IntErrorKind::NegOverflow), + Some(count) => Ok(Self { + length: self.length, + count, + }), + } + } } #[cfg(test)] @@ -92,18 +81,18 @@ mod test { use std::time::Duration; - use crate::protocol::clock::period::{Period, PeriodsTotals}; + use crate::protocol::clock::period::Period; #[test] fn it_should_get_the_total_time_of_a_period() { assert_eq!(Period::default().total_time().unwrap().unwrap(), Duration::ZERO); assert_eq!( - Period::from_sec(12, 12).total_time().unwrap().unwrap(), + Period::from_secs(12, 12).total_time().unwrap().unwrap(), Duration::from_secs(144) ); assert_eq!( - Period::from_sec(12, 12).total_time_end().unwrap().unwrap(), + Period::from_secs(12, 12).total_time_end().unwrap().unwrap(), Duration::from_secs(156) ); } From a569183a4b62030d8780ae3451fe555fe420a7e2 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 14 Sep 2022 21:46:00 +0200 Subject: [PATCH 7/7] refactor: keep `Period.count` input for functions consistent --- src/protocol/clock/period.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/protocol/clock/period.rs b/src/protocol/clock/period.rs index 0f41a8d98..5a32709b3 100644 --- a/src/protocol/clock/period.rs +++ b/src/protocol/clock/period.rs @@ -16,15 +16,15 @@ pub struct Period { impl Period { /// Returns a new `Period`. - pub fn new(length: &PeriodLength, count: &PeriodCount) -> Self { + pub fn new(length: &PeriodLength, count: PeriodCount) -> Self { Self { length: *length, - count: *count, + count, } } /// Returns a new `Period` from seconds. - pub const fn from_secs(seconds: u64, count: u64) -> Self { + pub const fn from_secs(seconds: u64, count: PeriodCount) -> Self { Self { length: Duration::from_secs(seconds), count,