use cljrs_value::{Value, ValueError, ValueResult};
use num_traits::ToPrimitive;
use std::sync::OnceLock;
use std::time::{Instant, SystemTime};
pub(crate) fn builtin_nanotime(_args: &[Value]) -> ValueResult<Value> {
match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(nanos) => Ok(Value::Long(
nanos
.as_nanos()
.to_i64()
.ok_or_else(|| ValueError::OutOfRange)?,
)),
Err(e) => Err(ValueError::Other(format!("{}", e))),
}
}
pub(crate) fn builtin_current_time_millis(_args: &[Value]) -> ValueResult<Value> {
match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(since_epoch) => Ok(Value::Long(
since_epoch
.as_millis()
.to_i64()
.ok_or_else(|| ValueError::OutOfRange)?,
)),
Err(e) => Err(ValueError::Other(format!("{}", e))),
}
}
fn epoch() -> Instant {
static EPOCH: OnceLock<Instant> = OnceLock::new();
*EPOCH.get_or_init(Instant::now)
}
pub(crate) fn builtin_system_nano_time(_args: &[Value]) -> ValueResult<Value> {
Ok(Value::Long(
epoch()
.elapsed()
.as_nanos()
.to_i64()
.ok_or_else(|| ValueError::OutOfRange)?,
))
}
#[cfg(not(target_arch = "wasm32"))]
pub fn init_clock() {
let _ = epoch();
}