nintypes 0.2.11

Nintondo shared types
Documentation
use std::time::{Duration, SystemTime};

#[derive(
    Clone,
    Copy,
    serde::Serialize,
    serde::Deserialize,
    Debug,
    derive_more::From,
    derive_more::Mul,
    derive_more::Div,
    derive_more::MulAssign,
    derive_more::DivAssign,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    derive_more::Add,
    derive_more::Sub,
    derive_more::AddAssign,
    derive_more::SubAssign,
    Hash,
    bytemuck::Pod,
    bytemuck::Zeroable,
)]
#[repr(C)]
#[serde(transparent)]
#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TimestampSec(pub u32);

#[derive(
    Clone,
    Copy,
    serde::Serialize,
    serde::Deserialize,
    Debug,
    derive_more::From,
    derive_more::Mul,
    derive_more::Div,
    derive_more::MulAssign,
    derive_more::DivAssign,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    derive_more::Add,
    derive_more::Sub,
    derive_more::AddAssign,
    derive_more::SubAssign,
    Hash,
    bytemuck::Pod,
    bytemuck::Zeroable,
)]
#[repr(C)]
#[serde(transparent)]
#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TimestampMs(pub u64);

#[derive(
    Clone,
    Copy,
    serde::Serialize,
    serde::Deserialize,
    Debug,
    derive_more::From,
    derive_more::Mul,
    derive_more::Div,
    derive_more::MulAssign,
    derive_more::DivAssign,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    derive_more::Add,
    derive_more::Sub,
    derive_more::AddAssign,
    derive_more::SubAssign,
    Hash,
    bytemuck::Pod,
    bytemuck::Zeroable,
)]
#[repr(C)]
#[serde(transparent)]
#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TimestampMicros(pub u64);

impl TimestampSec {
    pub const ZERO: Self = Self(0);
    pub const ONE_SEC: Self = Self(1);
    pub const ONE_MINUTE: Self = Self(60);
    pub const ONE_HOUR: Self = Self(60 * 60);
    pub const ONE_DAY: Self = Self(60 * 60 * 24);
    pub const MAX: Self = Self(u32::MAX);

    pub fn now() -> Self {
        Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as u32)
    }
    pub const fn sec(&self) -> u32 {
        self.0
    }
    pub const fn ms(&self) -> u64 {
        self.sec() as u64 * 1000
    }

    pub fn elapsed(&self) -> Option<Self> {
        Self::now().0.checked_sub(self.0).map(Self)
    }
}
impl TimestampMs {
    pub const ZERO: Self = Self(0);
    pub const ONE_MS: Self = Self(1);
    pub const ONE_SEC: Self = Self(1000);
    pub const ONE_MINUTE: Self = Self(1000 * 60);
    pub const ONE_HOUR: Self = Self(1000 * 60 * 60);
    pub const ONE_DAY: Self = Self(1000 * 60 * 60 * 24);
    pub const MAX: Self = Self(u64::MAX);

    pub fn now() -> Self {
        Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64)
    }
    pub const fn sec(&self) -> u32 {
        (self.ms() / 1000) as u32
    }
    pub const fn ms(&self) -> u64 {
        self.0
    }

    pub fn elapsed(&self) -> Option<Self> {
        Self::now().0.checked_sub(self.0).map(Self)
    }
}
impl TimestampMicros {
    pub const ZERO: Self = Self(0);
    pub const ONE_MICROS: Self = Self(1);
    pub const ONE_MS: Self = Self(1000);
    pub const ONE_SEC: Self = Self(1000 * 1000);
    pub const ONE_MINUTE: Self = Self(1000 * 1000 * 60);
    pub const ONE_HOUR: Self = Self(1000 * 1000 * 60 * 60);
    pub const ONE_DAY: Self = Self(1000 * 1000 * 60 * 60 * 24);
    pub const MAX: Self = Self(u64::MAX);

    pub fn now() -> Self {
        Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_micros() as u64)
    }
    pub const fn sec(&self) -> u32 {
        (self.ms() / 1000) as u32
    }
    pub const fn ms(&self) -> u64 {
        self.0 / 1000
    }
    pub const fn micros(&self) -> u64 {
        self.0
    }

    pub fn elapsed(&self) -> Option<Self> {
        Self::now().0.checked_sub(self.0).map(Self)
    }
}

impl From<SystemTime> for TimestampMs {
    fn from(value: SystemTime) -> Self {
        Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64)
    }
}
impl From<SystemTime> for TimestampSec {
    fn from(value: SystemTime) -> Self {
        Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as u32)
    }
}
impl From<SystemTime> for TimestampMicros {
    fn from(value: SystemTime) -> Self {
        Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_micros() as u64)
    }
}

impl From<TimestampMs> for SystemTime {
    fn from(value: TimestampMs) -> Self {
        SystemTime::UNIX_EPOCH + Duration::from_millis(value.0)
    }
}
impl From<TimestampSec> for SystemTime {
    fn from(value: TimestampSec) -> Self {
        SystemTime::UNIX_EPOCH + Duration::from_secs(value.0 as u64)
    }
}
impl From<TimestampMicros> for SystemTime {
    fn from(value: TimestampMicros) -> Self {
        SystemTime::UNIX_EPOCH + Duration::from_micros(value.0)
    }
}

pub mod ts_sec_str {
    use serde::{Deserialize, Serialize};

    use super::TimestampSec;

    pub fn serialize<S: serde::Serializer>(ts: &TimestampSec, ser: S) -> Result<S::Ok, S::Error> {
        ts.0.to_string().serialize(ser)
    }
    pub fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<TimestampSec, D::Error> {
        String::deserialize(de)?
            .parse::<u32>()
            .map(TimestampSec)
            .map_err(|_| serde::de::Error::custom("invalid timestamp sec num"))
    }
}
pub mod ts_ms_str {
    use serde::{Deserialize, Serialize};

    use super::TimestampMs;

    pub fn serialize<S: serde::Serializer>(ts: &TimestampMs, ser: S) -> Result<S::Ok, S::Error> {
        ts.0.to_string().serialize(ser)
    }
    pub fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<TimestampMs, D::Error> {
        String::deserialize(de)?
            .parse::<u64>()
            .map(TimestampMs)
            .map_err(|_| serde::de::Error::custom("invalid timestamp ms num"))
    }
}

pub mod ts_micros_str {
    use serde::{Deserialize, Serialize};

    use super::TimestampMicros;

    pub fn serialize<S: serde::Serializer>(ts: &TimestampMicros, ser: S) -> Result<S::Ok, S::Error> {
        ts.0.to_string().serialize(ser)
    }
    pub fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<TimestampMicros, D::Error> {
        String::deserialize(de)?
            .parse::<u64>()
            .map(TimestampMicros)
            .map_err(|_| serde::de::Error::custom("invalid timestamp micros num"))
    }
}