use core::ops::Add;
use serde::{Deserialize, Serialize};
pub const TIME_MAX: u64 = 0xffffffffff;
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[repr(C)]
pub struct Instant(u64);
impl Instant {
pub fn new(value: u64) -> Option<Self> {
if value <= TIME_MAX {
Some(Instant(value))
} else {
None
}
}
pub(crate) unsafe fn new_unchecked(value: u64) -> Self {
Instant(value)
}
pub fn value(&self) -> u64 {
self.0
}
pub fn duration_since(&self, earlier: Instant) -> Duration {
if self.value() >= earlier.value() {
Duration(self.value() - earlier.value())
} else {
Duration(TIME_MAX - earlier.value() + self.value() + 1)
}
}
}
impl Add<Duration> for Instant {
type Output = Instant;
fn add(self, rhs: Duration) -> Self::Output {
let value = (self.value() + rhs.value()) % (TIME_MAX + 1);
Instant::new(value).unwrap()
}
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[repr(C)]
pub struct Duration(u64);
impl Duration {
pub fn new(value: u64) -> Option<Self> {
if value <= TIME_MAX {
Some(Duration(value))
} else {
None
}
}
pub fn from_nanos(nanos: u32) -> Self {
Duration::new(nanos as u64 * 64).unwrap()
}
pub fn value(&self) -> u64 {
self.0
}
}