use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
pub(crate) const MILLIS_PER_SECOND: u64 = 1_000;
pub(crate) const MILLIS_PER_SECOND_F64: f64 = MILLIS_PER_SECOND as f64;
pub(crate) const SECONDS_PER_MINUTE: u64 = 60;
pub(crate) const SECONDS_PER_HOUR: u64 = SECONDS_PER_MINUTE * 60;
pub(crate) const SECONDS_PER_DAY: u64 = SECONDS_PER_HOUR * 24;
#[inline]
pub(crate) fn saturating_usize_to_i32(value: usize) -> i32 {
i32::try_from(value).unwrap_or(i32::MAX)
}
#[inline]
pub(crate) fn saturating_u32_to_i32(value: u32) -> i32 {
i32::try_from(value).unwrap_or(i32::MAX)
}
#[inline]
pub(crate) fn saturating_usize_to_u32(value: usize) -> u32 {
u32::try_from(value).unwrap_or(u32::MAX)
}
#[inline]
pub(crate) fn saturating_usize_to_u64(value: usize) -> u64 {
u64::try_from(value).unwrap_or(u64::MAX)
}
#[inline]
pub(crate) fn nonnegative_i32(value: i32) -> i32 {
value.max(0)
}
#[inline]
pub(crate) fn positive_i32(value: i32) -> i32 {
value.max(1)
}
#[inline]
pub(crate) fn positive_usize(value: usize) -> usize {
value.max(1)
}
#[inline]
pub(crate) fn positive_i32_to_usize(value: i32) -> Option<usize> {
usize::try_from(value).ok().filter(|value| *value > 0)
}
#[inline]
pub(crate) fn duration_ms(start: Instant, end: Instant) -> f64 {
end.saturating_duration_since(start).as_secs_f64() * MILLIS_PER_SECOND_F64
}
#[inline]
pub(crate) fn duration_millis_u64(duration: Duration) -> u64 {
u64::try_from(duration.as_millis()).unwrap_or(u64::MAX)
}
#[inline]
pub(crate) fn positive_fair_share_i32(budget: i32, participant_count: i32) -> i32 {
(budget / participant_count.max(1)).max(1)
}
#[inline]
pub(crate) fn unix_time_ms() -> u64 {
system_time_unix_ms(SystemTime::now())
}
#[inline]
pub(crate) fn system_time_unix_ms(value: SystemTime) -> u64 {
value
.duration_since(UNIX_EPOCH)
.map(duration_millis_u64)
.unwrap_or(0)
}
#[cfg(test)]
#[path = "../tests/runtime/numeric_tests.rs"]
mod numeric_tests;