use crate::core::TimestampMarker;
use core::{marker::PhantomData, ops, time::Duration};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Timestamp<M>(Duration, PhantomData<M>);
impl<M> Timestamp<M> {
pub fn new(duration: Duration) -> Self {
Self(duration, PhantomData)
}
pub fn abs_diff(self, other: Self) -> Duration {
if let Some(res) = self.0.checked_sub(other.0) {
res
} else {
other.0.checked_sub(self.0).unwrap()
}
}
pub fn checked_sub(self, other: Self) -> Option<Duration> {
self.0.checked_sub(other.0)
}
}
impl<T> PartialEq for Timestamp<T> {
fn eq(&self, other: &Timestamp<T>) -> bool {
self.0.eq(&other.0)
}
}
impl<T> Eq for Timestamp<T> {}
impl<T> PartialOrd for Timestamp<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<T> Ord for Timestamp<T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl<M> ops::Deref for Timestamp<M> {
type Target = Duration;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<M> From<Duration> for Timestamp<M> {
fn from(value: Duration) -> Self {
Self(value, PhantomData)
}
}
impl<M> From<Timestamp<M>> for Duration {
fn from(value: Timestamp<M>) -> Self {
value.0
}
}
impl<M> core::fmt::Display for Timestamp<M>
where
M: TimestampMarker,
{
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
write!(fmt, "{:?} {}", self.0, M::display_str_short())
}
}