use std::{sync::LazyLock, thread_local};
use crate::{
generator::{BasicMonoUlidGenerator, BasicUlidGenerator, Poll},
id::{Id, ULID},
rand::{RandSource, ThreadRandom},
time::{MonotonicClock, UNIX_EPOCH},
};
static GLOBAL_MONOTONIC_CLOCK: LazyLock<MonotonicClock> =
LazyLock::new(|| MonotonicClock::with_epoch(UNIX_EPOCH));
thread_local! {
static BASIC_ULID: BasicUlidGenerator<ULID, MonotonicClock, ThreadRandom> =
BasicUlidGenerator::new(
GLOBAL_MONOTONIC_CLOCK.clone(),
ThreadRandom
);
static BASIC_MONO_ULID: BasicMonoUlidGenerator<ULID, MonotonicClock, ThreadRandom> =
BasicMonoUlidGenerator::new(
GLOBAL_MONOTONIC_CLOCK.clone(),
ThreadRandom
);
}
pub struct Ulid;
impl Ulid {
#[must_use]
pub fn new_ulid() -> ULID {
BASIC_ULID.with(|g| match g.poll_id() {
Poll::Ready { id } => id,
Poll::Pending { .. } => unreachable!("basic ULID generator should never need to yield"),
})
}
#[must_use]
pub fn new_ulid_mono(f: impl FnMut(<ULID as Id>::Ty)) -> ULID {
BASIC_MONO_ULID.with(|g| g.next_id(f))
}
#[must_use]
pub fn from_timestamp(timestamp: <ULID as Id>::Ty) -> ULID {
ULID::from_timestamp(timestamp)
}
pub fn from_timestamp_and_rand<R>(timestamp: <ULID as Id>::Ty, rng: &R) -> ULID
where
R: RandSource<<ULID as Id>::Ty>,
{
ULID::from_timestamp_and_rand(timestamp, rng)
}
#[must_use]
pub fn from_datetime(datetime: std::time::SystemTime) -> ULID {
ULID::from_datetime(datetime)
}
pub fn from_datetime_and_rand<R>(datetime: std::time::SystemTime, rng: &R) -> ULID
where
R: RandSource<<ULID as Id>::Ty>,
{
ULID::from_datetime_and_rand(datetime, rng)
}
}