use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{Display, Formatter};
use std::ops::Add;
use std::time::SystemTime;
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
pub struct UnixTimestamp(u64);
impl Serialize for UnixTimestamp {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&self.0.to_string())
}
}
impl<'de> Deserialize<'de> for UnixTimestamp {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
let ts = s
.parse::<u64>()
.map_err(|_| serde::de::Error::custom("timestamp must be a non-negative integer"))?;
Ok(UnixTimestamp(ts))
}
}
impl Display for UnixTimestamp {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl Add<u64> for UnixTimestamp {
type Output = Self;
fn add(self, rhs: u64) -> Self::Output {
UnixTimestamp(self.0 + rhs)
}
}
impl UnixTimestamp {
pub fn from_secs(secs: u64) -> Self {
Self(secs)
}
pub fn now() -> Self {
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("SystemTime before UNIX epoch?!?")
.as_secs();
Self(now)
}
pub fn as_secs(&self) -> u64 {
self.0
}
}