use crate::{
core::{
optional::{gen_optional, NSTDOptional},
time::{
nstd_core_time_duration_get, nstd_core_time_duration_nanoseconds,
nstd_core_time_duration_new, nstd_core_time_duration_seconds, NSTDDuration,
},
},
NSTDFloat64, NSTDInt64, NSTDUInt32,
};
use core::mem::MaybeUninit;
use libc::{clock_gettime, timespec, CLOCK_REALTIME};
use nstdapi::nstdapi;
#[nstdapi]
#[derive(Clone, Copy, PartialEq)]
pub struct NSTDUnixTime {
duration: NSTDDuration,
}
impl NSTDUnixTime {
#[inline]
#[allow(dead_code)]
pub(crate) const fn from_duration(duration: NSTDDuration) -> Self {
Self { duration }
}
}
impl From<timespec> for NSTDUnixTime {
#[allow(clippy::cast_precision_loss)]
fn from(value: timespec) -> Self {
const NANOS_IN_SEC: NSTDFloat64 = 1_000_000_000.0;
let mut seconds = value.tv_sec as _;
seconds += value.tv_nsec as NSTDFloat64 / NANOS_IN_SEC;
#[allow(unused_unsafe)]
unsafe {
Self {
duration: nstd_core_time_duration_new(seconds),
}
}
}
}
gen_optional!(NSTDUnixOptionalTime, NSTDUnixTime);
#[inline]
#[nstdapi]
pub fn nstd_os_unix_time_now() -> NSTDUnixOptionalTime {
let mut timespec = MaybeUninit::uninit();
if unsafe { clock_gettime(CLOCK_REALTIME, timespec.as_mut_ptr()) } == 0 {
return NSTDOptional::Some(NSTDUnixTime::from(unsafe { timespec.assume_init() }));
}
NSTDOptional::None
}
#[inline]
#[nstdapi]
pub const fn nstd_os_unix_time_get(time: NSTDUnixTime) -> NSTDFloat64 {
nstd_core_time_duration_get(time.duration)
}
#[inline]
#[nstdapi]
pub const fn nstd_os_unix_time_seconds(time: NSTDUnixTime) -> NSTDInt64 {
nstd_core_time_duration_seconds(time.duration)
}
#[inline]
#[nstdapi]
pub fn nstd_os_unix_time_nanoseconds(time: NSTDUnixTime) -> NSTDUInt32 {
nstd_core_time_duration_nanoseconds(time.duration)
}
#[inline]
#[nstdapi]
pub fn nstd_os_unix_time_add(time: NSTDUnixTime, duration: NSTDDuration) -> NSTDUnixTime {
let secs = nstd_core_time_duration_get(time.duration) + nstd_core_time_duration_get(duration);
NSTDUnixTime {
duration: nstd_core_time_duration_new(secs),
}
}
#[inline]
#[nstdapi]
pub fn nstd_os_unix_time_sub(time: NSTDUnixTime, duration: NSTDDuration) -> NSTDUnixTime {
let secs = nstd_core_time_duration_get(time.duration) - nstd_core_time_duration_get(duration);
NSTDUnixTime {
duration: nstd_core_time_duration_new(secs),
}
}