use serde::{Deserialize, Serialize};
pub trait Timestamp: PartialOrd + Ord + Clone + std::fmt::Debug + 'static {
const MAX: Self;
const MIN: Self;
fn merge(&self, other: &Self) -> Self;
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct NoTime;
impl PartialOrd for NoTime {
fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
None
}
}
pub trait MaybeTime: std::fmt::Debug + Clone + PartialOrd + 'static {
fn try_merge(&self, other: &Self) -> Option<Self>;
const CHECK_FINISHED: fn(&Option<Self>) -> bool;
}
impl<T> MaybeTime for T
where
T: Timestamp + Clone + 'static,
{
fn try_merge(&self, other: &Self) -> Option<Self> {
Some(self.merge(other))
}
const CHECK_FINISHED: fn(&Option<Self>) -> bool =
|opt_t| opt_t.as_ref().is_some_and(|t| *t == T::MAX);
}
impl MaybeTime for NoTime {
fn try_merge(&self, _other: &Self) -> Option<Self> {
Some(NoTime)
}
const CHECK_FINISHED: fn(&Option<Self>) -> bool = |_| true;
}
macro_rules! timestamp_impl {
($t:ty) => {
impl Timestamp for $t {
const MAX: $t = <$t>::MAX;
const MIN: $t = <$t>::MIN;
fn merge(&self, other: &$t) -> $t {
*self.min(other)
}
}
};
}
timestamp_impl!(usize);
timestamp_impl!(u8);
timestamp_impl!(u16);
timestamp_impl!(u32);
timestamp_impl!(u64);
timestamp_impl!(u128);
timestamp_impl!(isize);
timestamp_impl!(i8);
timestamp_impl!(i16);
timestamp_impl!(i32);
timestamp_impl!(i64);
timestamp_impl!(i128);