use std::fmt::Display;
use borsh::BorshSerialize;
use newtype_ops::newtype_ops;
use serde::{Deserialize, Serialize};
#[cfg(feature = "ts")]
use ts_rs::TS;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize, BorshSerialize)]
#[cfg_attr(feature = "ts", derive(TS), ts(export))]
pub struct Epoch(#[cfg_attr(feature = "ts", ts(type = "number"))] pub u64);
impl Epoch {
pub const fn zero() -> Self {
Self(0)
}
pub const fn max() -> Self {
Self(u64::MAX)
}
pub const fn as_u64(self) -> u64 {
self.0
}
pub fn is_zero(&self) -> bool {
self.0 == 0
}
pub fn to_be_bytes(self) -> [u8; 8] {
self.0.to_be_bytes()
}
pub fn saturating_sub<T: Into<Epoch>>(&self, other: T) -> Epoch {
Epoch(self.0.saturating_sub(other.into().0))
}
pub fn checked_sub<T: Into<Self>>(&self, other: T) -> Option<Epoch> {
let other = other.into();
self.0.checked_sub(other.as_u64()).map(Epoch)
}
pub fn checked_add<T: Into<Self>>(&self, other: T) -> Option<Epoch> {
let other = other.into();
self.0.checked_add(other.as_u64()).map(Epoch)
}
}
impl From<u64> for Epoch {
fn from(e: u64) -> Self {
Self(e)
}
}
impl PartialEq<u64> for Epoch {
fn eq(&self, other: &u64) -> bool {
self.0 == *other
}
}
impl PartialEq<Epoch> for u64 {
fn eq(&self, other: &Epoch) -> bool {
*self == other.0
}
}
impl Display for Epoch {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Epoch({})", self.0)
}
}
newtype_ops! { [Epoch] {add sub mul div} {:=} Self Self }
newtype_ops! { [Epoch] {add sub mul div} {:=} &Self &Self }
newtype_ops! { [Epoch] {add sub mul div} {:=} Self &Self }