use candid::CandidType;
use serde::{Deserialize, Serialize};
use std::ops::Add;
use std::ops::Sub;
#[cfg(not(target_arch = "wasm32"))]
use crate::mocks::time_mock as ic_timestamp;
#[cfg(target_arch = "wasm32")]
use ic_cdk::api::time as ic_timestamp;
mod test;
mod traits;
#[derive(
Default, CandidType, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Clone, Debug,
)]
pub struct NanoTimeStamp(pub u64);
impl Add for NanoTimeStamp {
type Output = Self;
fn add(self, other: Self) -> Self {
NanoTimeStamp(self.0 + other.0)
}
}
impl Sub for NanoTimeStamp {
type Output = Self;
fn sub(self, other: Self) -> Self {
NanoTimeStamp(self.0 - other.0)
}
}
impl NanoTimeStamp {
pub const NS_PER_MILLISECOND: u64 = 1_000_000;
pub const NS_PER_SECOND: u64 = Self::NS_PER_MILLISECOND * 1_000;
pub const NS_PER_MINUTE: u64 = Self::NS_PER_SECOND * 60;
pub const NS_PER_HOUR: u64 = Self::NS_PER_MINUTE * 60;
pub const NS_PER_DAY: u64 = Self::NS_PER_HOUR * 24;
pub fn now() -> Self {
NanoTimeStamp(ic_timestamp())
}
pub fn days_from_now(days: u64) -> Self {
let ns_to_add = days * Self::NS_PER_DAY;
NanoTimeStamp(ic_timestamp() + ns_to_add)
}
pub fn from_le_bytes(bytes: [u8; 8]) -> Self {
NanoTimeStamp(u64::from_le_bytes(bytes))
}
pub fn elapsed(&self) -> Self {
let now = NanoTimeStamp::now();
if self > &now {
NanoTimeStamp(0)
} else {
NanoTimeStamp(now.0 - self.0)
}
}
pub fn to_le_bytes(&self) -> [u8; 8] {
self.0.to_le_bytes()
}
pub fn to_secs(&self) -> u64 {
self.0 / Self::NS_PER_SECOND
}
pub fn to_millis(&self) -> u64 {
self.0 / Self::NS_PER_MILLISECOND
}
pub fn as_global_timer(&self) -> i64 {
self.0 as i64
}
pub fn has_passed(&self) -> bool {
let now = NanoTimeStamp::now();
self < &now
}
pub fn in_future(&self) -> bool {
let now = NanoTimeStamp::now();
self > &now
}
pub fn time_until(&self) -> u64 {
let now = NanoTimeStamp::now();
if self > &now {
self.0 - now.0
} else {
0
}
}
pub fn time_since(&self) -> u64 {
let now = NanoTimeStamp::now();
if self < &now {
now.0 - self.0
} else {
0
}
}
pub fn rate_limit_exceeded(&self, rate_limit: u64) -> bool {
let now = NanoTimeStamp::now();
let time_since = now.0 - self.0;
time_since < rate_limit
}
pub fn add_secs(&self, secs: u64) -> Self {
let ns_to_add = secs * Self::NS_PER_SECOND;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn add_mins(&self, mins: u64) -> Self {
let ns_to_add = mins * Self::NS_PER_MINUTE;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn add_hours(&self, hours: u64) -> Self {
let ns_to_add = hours * Self::NS_PER_HOUR;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn add_days(&self, days: u64) -> Self {
let ns_to_add = days * Self::NS_PER_DAY;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn get_secs(&self) -> u64 {
self.0 / Self::NS_PER_SECOND
}
pub fn get_mins(&self) -> u64 {
self.0 / Self::NS_PER_MINUTE
}
pub fn get_hours(&self) -> u64 {
self.0 / Self::NS_PER_HOUR
}
pub fn get_days(&self) -> u64 {
self.0 / Self::NS_PER_DAY
}
}