use std::time::{SystemTime, UNIX_EPOCH};
use crate::domain::model::record_ref::{DecisionRecordRef, IssueRef};
use crate::domain::model::ulid::Ulid;
use crate::domain::usecases::decision_record::DecisionRecordIdGenerator;
use crate::domain::usecases::issue::IssueIdGenerator;
use crate::domain::usecases::migrate::legacy::tsid::Tsid;
fn now_millis() -> i64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_millis() as i64)
.unwrap_or(0)
}
fn random_u128() -> u128 {
use rand::RngCore;
let mut buf = [0u8; 16];
rand::rngs::OsRng.fill_bytes(&mut buf);
u128::from_le_bytes(buf)
}
pub fn tsid_from_millis(unix_ms: i64) -> Tsid {
use rand::RngCore;
let mask = (1u32 << crate::domain::usecases::migrate::legacy::tsid::RANDOM_BITS) - 1;
Tsid::from_millis_with_random(unix_ms, rand::rngs::OsRng.next_u32() & mask)
}
fn fresh_ulid() -> Ulid {
Ulid::from_millis_with_random(now_millis(), random_u128())
}
pub fn ulid_from_millis(unix_ms: i64) -> Ulid {
Ulid::from_millis_with_random(unix_ms, random_u128())
}
fn format_id(prefix: &str) -> String {
format!("{}-{}", prefix.trim_end_matches('-'), fresh_ulid())
}
pub struct UlidIssueIdGenerator {
pub id_prefix: String,
}
impl IssueIdGenerator for UlidIssueIdGenerator {
fn next_id(&self) -> anyhow::Result<IssueRef> {
IssueRef::parse_v5(&format_id(&self.id_prefix))
}
}
pub struct UlidDecisionRecordIdGenerator {
pub id_prefix: String,
}
impl DecisionRecordIdGenerator for UlidDecisionRecordIdGenerator {
fn next_id(&self) -> anyhow::Result<DecisionRecordRef> {
DecisionRecordRef::parse_v5(&format_id(&self.id_prefix))
}
}