use std::ops::{Add, AddAssign, Sub};
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct Duration(u64);
impl Duration {
pub const ZERO: Self = Self(0);
#[must_use]
pub const fn from_nanos(nanos: u64) -> Self {
Self(nanos)
}
#[must_use]
pub const fn from_micros(micros: u64) -> Self {
Self(micros.saturating_mul(1_000))
}
#[must_use]
pub const fn from_millis(millis: u64) -> Self {
Self(millis.saturating_mul(1_000_000))
}
#[must_use]
pub const fn from_secs(seconds: u64) -> Self {
Self(seconds.saturating_mul(1_000_000_000))
}
#[must_use]
pub const fn as_nanos(self) -> u64 {
self.0
}
#[must_use]
pub fn as_secs_f64(self) -> f64 {
self.0 as f64 / 1_000_000_000.0
}
}
impl Add for Duration {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0.saturating_add(rhs.0))
}
}
impl AddAssign for Duration {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl Sub for Duration {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0.saturating_sub(rhs.0))
}
}
impl From<std::time::Duration> for Duration {
fn from(value: std::time::Duration) -> Self {
Self(u64::try_from(value.as_nanos()).unwrap_or(u64::MAX))
}
}
impl From<Duration> for std::time::Duration {
fn from(value: Duration) -> Self {
Self::from_nanos(value.0)
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct Time(u64);
impl Time {
pub const ZERO: Self = Self(0);
#[must_use]
pub const fn from_nanos(nanos: u64) -> Self {
Self(nanos)
}
#[must_use]
pub const fn as_nanos(self) -> u64 {
self.0
}
#[must_use]
pub const fn duration_since(self, earlier: Self) -> Duration {
Duration::from_nanos(self.0.saturating_sub(earlier.0))
}
}
impl Add<Duration> for Time {
type Output = Self;
fn add(self, rhs: Duration) -> Self::Output {
Self(self.0.saturating_add(rhs.as_nanos()))
}
}
impl Sub<Time> for Time {
type Output = Duration;
fn sub(self, rhs: Time) -> Self::Output {
self.duration_since(rhs)
}
}