tiltflake 0.3.0

Tiltflake is a distributed database that uses the flake algorithm to generate unique IDs.
Documentation
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)]
/// Represents a unique identifier generated by the Tiltflake system.
///
/// The `TiltflakeId` is a 64-bit integer that encodes a timestamp, machine ID, and sequence number.
pub struct TiltflakeId(pub(crate) u64);

impl TiltflakeId {
	/// Extracts the timestamp from the `TiltflakeId`.
	///
	/// # Arguments
	///
	/// * `generator` - A reference to the `Tiltflake` generator, which provides the custom epoch.
	///
	/// # Returns
	///
	/// A `DateTime<Utc>` representing the timestamp encoded in the ID.
	///
	/// # Panics
	///
	/// This function will panic if the raw timestamp cannot be converted to an `i64`.
	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")),
			)
	}

	/// Extracts the machine ID from the `TiltflakeId`.
	///
	/// # Returns
	///
	/// A `u16` representing the machine ID encoded in the ID.
	pub const fn machine_id(self) -> u16 {
		((self.0 >> 12) & 0x3FF) as u16
	}

	/// Extracts the sequence number from the `TiltflakeId`.
	///
	/// # Returns
	///
	/// A `u16` representing the sequence number encoded in the ID.
	pub const fn sequence(self) -> u16 {
		(self.0 & 0xFFF) as u16
	}

	/// Returns the raw 64-bit integer value of the `TiltflakeId`.
	///
	/// # Returns
	///
	/// A `u64` representing the raw value of the ID.
	pub const fn into_inner(self) -> u64 {
		self.0
	}

	/// Creates a new `TiltflakeId` from a raw `u64` value.
	///
	/// # Arguments
	///
	/// * `value` - The raw `u64` value to wrap as a `TiltflakeId`.
	///
	/// # Returns
	///
	/// A `TiltflakeId` containing the provided value.
	pub const fn from_u64(value: u64) -> Self {
		Self(value)
	}

	/// Returns the inner `u64` value of the `TiltflakeId`.
	///
	/// # Returns
	///
	/// The raw `u64` value contained in the `TiltflakeId`.
	pub const fn as_u64(self) -> u64 {
		self.0
	}
}

impl fmt::Display for TiltflakeId {
	/// Formats the `TiltflakeId` as a string.
	///
	/// # Arguments
	///
	/// * `f` - A mutable reference to the formatter.
	///
	/// # Returns
	///
	/// A `fmt::Result` indicating success or failure.
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		write!(f, "{}", self.0)
	}
}

impl FromStr for TiltflakeId {
	type Err = std::num::ParseIntError;

	/// Parses a `TiltflakeId` from a string.
	///
	/// # Arguments
	///
	/// * `s` - A string slice containing the ID to parse.
	///
	/// # Returns
	///
	/// A `Result` containing the parsed `TiltflakeId` or a `ParseIntError` if parsing fails.
	fn from_str(s: &str) -> Result<Self, Self::Err> {
		Ok(Self(s.parse()?))
	}
}