hara-native 0.1.10

HAL-free native host runtime and package launcher for Hara
Documentation
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
pub(crate) fn time_ms() -> i64 {
    use std::time::{SystemTime, UNIX_EPOCH};

    match SystemTime::now().duration_since(UNIX_EPOCH) {
        Ok(duration) => i64::try_from(duration.as_millis()).unwrap_or(i64::MAX),
        Err(error) => -i64::try_from(error.duration().as_millis()).unwrap_or(i64::MAX),
    }
}

#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
pub(crate) fn time_ns() -> i64 {
    use std::sync::OnceLock;
    use std::time::Instant;

    static ORIGIN: OnceLock<Instant> = OnceLock::new();
    i64::try_from(ORIGIN.get_or_init(Instant::now).elapsed().as_nanos()).unwrap_or(i64::MAX)
}

#[cfg(all(target_arch = "wasm32", target_os = "unknown", feature = "raw-wasm"))]
#[link(wasm_import_module = "env")]
extern "C" {
    fn hara_time_ms() -> i64;
    fn hara_time_ns() -> i64;
}

#[cfg(all(target_arch = "wasm32", target_os = "unknown", feature = "raw-wasm"))]
pub(crate) fn time_ms() -> i64 {
    unsafe { hara_time_ms() }
}

#[cfg(all(target_arch = "wasm32", target_os = "unknown", feature = "raw-wasm"))]
pub(crate) fn time_ns() -> i64 {
    unsafe { hara_time_ns() }
}

#[cfg(all(
    target_arch = "wasm32",
    target_os = "unknown",
    not(feature = "raw-wasm")
))]
pub(crate) fn time_ms() -> i64 {
    js_sys::Date::now() as i64
}

#[cfg(all(
    target_arch = "wasm32",
    target_os = "unknown",
    not(feature = "raw-wasm")
))]
pub(crate) fn time_ns() -> i64 {
    use wasm_bindgen::{JsCast, JsValue};

    let global = js_sys::global();
    let performance = js_sys::Reflect::get(&global, &JsValue::from_str("performance"))
        .expect("browser performance clock is unavailable");
    let now = js_sys::Reflect::get(&performance, &JsValue::from_str("now"))
        .expect("browser performance.now is unavailable")
        .dyn_into::<js_sys::Function>()
        .expect("browser performance.now is not callable");
    let milliseconds = now
        .call0(&performance)
        .expect("browser performance.now failed")
        .as_f64()
        .expect("browser performance.now returned a non-number");
    (milliseconds * 1_000_000.0) as i64
}

#[cfg(all(test, any(not(target_arch = "wasm32"), target_os = "wasi")))]
mod tests {
    #[test]
    fn wall_clock_is_epoch_milliseconds() {
        assert!(super::time_ms() > 1_000_000_000_000);
    }

    #[test]
    fn monotonic_clock_is_runtime_local_and_nondecreasing() {
        let before = super::time_ns();
        let after = super::time_ns();
        assert!(before >= 0);
        assert!(after >= before);
    }
}