use crate::flake::Tiltflake;
use chrono::{DateTime, Utc};
use std::fmt;
use std::str::FromStr;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TiltflakeId(pub(crate) u64);
impl TiltflakeId {
pub fn timestamp(self, generator: &Tiltflake) -> DateTime<Utc> {
let raw_timestamp = self.0 >> 22;
generator.custom_epoch
+ chrono::Duration::milliseconds(
i64::try_from(raw_timestamp)
.unwrap_or_else(|_| panic!("raw_timestamp out of range for i64")),
)
}
pub const fn machine_id(self) -> u16 {
((self.0 >> 12) & 0x3FF) as u16
}
pub const fn sequence(self) -> u16 {
(self.0 & 0xFFF) as u16
}
pub const fn into_inner(self) -> u64 {
self.0
}
pub const fn from_u64(value: u64) -> Self {
Self(value)
}
pub const fn as_u64(self) -> u64 {
self.0
}
}
impl fmt::Display for TiltflakeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl FromStr for TiltflakeId {
type Err = std::num::ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.parse()?))
}
}