use derive_more::{Add, AddAssign, Display, From, Into, Sub, Sum};
pub type Time = u64;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, From, Into, Display, Debug)]
pub struct Offset {
val: Time,
}
impl Offset {
pub const fn from_time_zero(delta: Duration) -> Offset {
Offset { val: delta.val }
}
pub const fn closed_from_time_zero(delta: Duration) -> Offset {
Offset { val: delta.val - 1 }
}
pub const fn since_time_zero(self) -> Duration {
Duration { val: self.val }
}
pub const fn closed_since_time_zero(self) -> Duration {
Duration { val: self.val + 1 }
}
pub fn distance_to(self, t: Offset) -> Duration {
debug_assert!(self.val <= t.val);
Duration::from(t.val - self.val)
}
}
impl std::ops::Add<Duration> for Offset {
type Output = Offset;
fn add(self, delta: Duration) -> Offset {
Offset {
val: self.val + delta.val,
}
}
}
#[derive(
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
From,
Into,
Display,
Debug,
Add,
AddAssign,
Sub,
Sum,
)]
pub struct Duration {
val: Time,
}
impl Duration {
pub const fn is_non_zero(self) -> bool {
self.val > 0
}
pub const fn is_zero(self) -> bool {
self.val == 0
}
pub const fn zero() -> Duration {
Duration { val: 0 }
}
pub const fn epsilon() -> Duration {
Duration { val: 1 }
}
#[must_use]
pub const fn saturating_sub(&self, rhs: Duration) -> Duration {
Duration {
val: self.val.saturating_sub(rhs.val),
}
}
}
impl From<Service> for Duration {
fn from(s: Service) -> Duration {
Duration::from(s.val)
}
}
impl std::ops::Mul<u64> for Duration {
type Output = Duration;
fn mul(self, factor: u64) -> Duration {
Duration::from(self.val * factor)
}
}
impl std::ops::Div<Duration> for Duration {
type Output = u64;
fn div(self, divisor: Duration) -> u64 {
self.val / divisor.val
}
}
impl std::ops::Rem<Duration> for Duration {
type Output = Duration;
fn rem(self, divisor: Duration) -> Duration {
Duration::from(self.val % divisor.val)
}
}
#[derive(
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
From,
Into,
Display,
Debug,
Add,
Sub,
AddAssign,
Sum,
)]
pub struct Service {
val: Time,
}
impl Service {
pub fn none() -> Service {
Service::from(0)
}
pub fn is_none(self) -> bool {
self.val == 0
}
pub const fn in_interval(d: Duration) -> Service {
Service { val: d.val }
}
pub const fn epsilon() -> Service {
Service { val: 1 }
}
#[must_use]
pub const fn saturating_sub(&self, rhs: Service) -> Service {
Service {
val: self.val.saturating_sub(rhs.val),
}
}
}
impl From<Duration> for Service {
fn from(d: Duration) -> Service {
Service::in_interval(d)
}
}
impl std::ops::Mul<u64> for Service {
type Output = Service;
fn mul(self, factor: u64) -> Service {
Service::from(self.val * factor)
}
}