ti64 0.1.5

A simple i64 ms since epoch timestamp.
Documentation
use std::{fmt::Debug, ops::Add};

use instant::SystemTime;

use serde_derive::{Deserialize, Serialize};
use time::{format_description::well_known::Rfc3339, OffsetDateTime};

#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct MsSinceEpoch(#[serde(with = "ms_to_human")] pub i64);

impl MsSinceEpoch {
    fn now() -> Self {
        MsSinceEpoch(
            SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap()
                .as_millis() as i64,
        )
    }
}

impl Debug for MsSinceEpoch {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{:?}",
            OffsetDateTime::from_unix_timestamp_nanos(self.0 as i128 * 1_000_000)
                .unwrap()
                .format(&Rfc3339)
                .unwrap()
        )
    }
}

pub fn now() -> MsSinceEpoch {
    MsSinceEpoch::now()
}

impl Add<i64> for MsSinceEpoch {
    type Output = Self;

    fn add(self, rhs: i64) -> Self::Output {
        Self(self.0 + rhs)
    }
}

mod ms_to_human {
    use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
    use time::{format_description::well_known::Rfc3339, OffsetDateTime};

    pub fn serialize<S>(ms: &i64, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        OffsetDateTime::from_unix_timestamp_nanos(*ms as i128 * 1_000_000)
            .unwrap()
            .format(&Rfc3339)
            .unwrap()
            .serialize(serializer)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<i64, D::Error>
    where
        D: Deserializer<'de>,
    {
        // TODO(optimization): deserialize to borrowed string
        let s = String::deserialize(deserializer)?;
        let dt =
            OffsetDateTime::parse(&s, &Rfc3339).map_err(|err| D::Error::custom(err.to_string()))?;
        Ok((dt.unix_timestamp_nanos() / 1_000_000) as i64)
    }
}