use crate::Error;
use derive_more::{AsMut, AsRef, Deref, Display, From, Into};
use serde::{Deserialize, Serialize};
use std::ops::{Add, Sub};
use std::time::Duration;
#[derive(
AsMut,
AsRef,
Clone,
Copy,
Debug,
Deref,
Deserialize,
Display,
Eq,
From,
Into,
Ord,
PartialEq,
PartialOrd,
Serialize,
)]
pub struct Unixtime(pub i64);
impl Unixtime {
pub fn now() -> Result<Unixtime, Error> {
Ok(Unixtime(std::time::UNIX_EPOCH.elapsed()?.as_secs() as i64))
}
#[allow(dead_code)]
pub(crate) fn mock() -> Unixtime {
Unixtime(1668572286)
}
}
impl Add<Duration> for Unixtime {
type Output = Self;
fn add(self, rhs: Duration) -> Self::Output {
Unixtime(self.0 + rhs.as_secs() as i64)
}
}
impl Sub<Duration> for Unixtime {
type Output = Self;
fn sub(self, rhs: Duration) -> Self::Output {
Unixtime(self.0 - rhs.as_secs() as i64)
}
}
impl Sub<Unixtime> for Unixtime {
type Output = Duration;
fn sub(self, rhs: Unixtime) -> Self::Output {
Duration::from_secs((self.0 - rhs.0).unsigned_abs())
}
}
#[cfg(test)]
mod test {
use super::*;
test_serde! {Unixtime, test_unixtime_serde}
#[test]
fn test_print_now() {
println!("NOW: {}", Unixtime::now().unwrap());
}
#[test]
fn test_unixtime_math() {
let now = Unixtime::now().unwrap();
let fut = now + std::time::Duration::from_secs(70);
assert!(fut > now);
assert_eq!(fut.0 - now.0, 70);
let back = fut - std::time::Duration::from_secs(70);
assert_eq!(now, back);
assert_eq!(now - back, std::time::Duration::ZERO);
}
}