use std::time::SystemTime;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Timestamp(pub u32);
impl Timestamp {
pub fn now() -> Self {
SystemTime::now().try_into().unwrap()
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum TimestampError {
Underflow,
Overflow,
}
impl From<u32> for Timestamp {
fn from(t: u32) -> Timestamp {
Timestamp(t)
}
}
impl From<Timestamp> for u32 {
fn from(t: Timestamp) -> u32 {
t.0
}
}
impl TryFrom<SystemTime> for Timestamp {
type Error = TimestampError;
fn try_from(st: SystemTime) -> Result<Timestamp, Self::Error> {
st.duration_since(SystemTime::UNIX_EPOCH)
.map_err(|_| TimestampError::Underflow)
.and_then(|t| t.as_secs().try_into().map_err(|_| TimestampError::Overflow))
.map(Timestamp)
}
}
#[cfg(feature = "chrono")]
impl<TZ: chrono::TimeZone> TryFrom<chrono::DateTime<TZ>> for Timestamp {
type Error = TimestampError;
fn try_from(dt: chrono::DateTime<TZ>) -> Result<Timestamp, Self::Error> {
let t = dt.with_timezone(&chrono::Utc).timestamp();
if t < 0 {
return Err(TimestampError::Underflow);
}
t.try_into()
.map_err(|_| TimestampError::Overflow)
.map(Timestamp)
}
}