use std::{fmt::Display, str::FromStr, sync::atomic::{AtomicU64, Ordering}}; use serde::{Deserialize, Serialize}; #[derive( Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, )] pub struct Id(pub u64); impl Id { #[inline] pub const fn get(&self) -> u64 { self.0 } pub fn unique() -> Self { Self(crate::timestamp_us()) } } impl Display for Id { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) } } impl FromStr for Id { type Err = ::Err; fn from_str(s: &str) -> Result { s.parse().map(Self) } } impl From for Id { fn from(value: u64) -> Self { Self(value) } } impl From for Id { fn from(value: usize) -> Self { Self(value as u64) } } impl TryFrom for Id { type Error = >::Error; fn try_from(value: i64) -> Result { u64::try_from(value).map(Self) } } impl PartialEq for Id { fn eq(&self, other: &u64) -> bool { self.0 == *other } } // --- Ids pub struct Ids { next: AtomicU64, } impl Ids { #[inline] pub const fn new() -> Self { Self { next: AtomicU64::new(1) } } #[inline] pub fn next(&self) -> Id { loop { let old = self.next.fetch_add(1, Ordering::Relaxed); if old != 0 { return Id(old); } } } #[inline] pub fn current(&self) -> Id { Id(self.next.load(Ordering::Relaxed)) } } impl Default for Ids { fn default() -> Self { Self::new() } }