use std::time::{Duration, Instant};
mod bit_pattern;
pub(crate) use bit_pattern::BitPattern;
pub(crate) mod value_history;
mod time_tricks;
pub(crate) use time_tricks::{already_happened, epoch_to_beginning, not_happening, InstantExt};
pub(crate) trait Soonest {
fn soonest(self, other: Self) -> Self;
}
impl<T: Default> Soonest for (Option<Instant>, T) {
fn soonest(self, other: Self) -> Self {
match (self, other) {
((Some(v1), s1), (Some(v2), s2)) => {
if v1 < v2 {
(Some(v1), s1)
} else {
(Some(v2), s2)
}
}
((None, _), (None, _)) => (None, T::default()),
((None, _), (v, s)) => (v, s),
((v, s), (None, _)) => (v, s),
}
}
}
pub(crate) fn calculate_rtt_ms(ntp_time: Duration, delay: u32, last_report: u32) -> Option<f32> {
if delay == 0 {
return None;
}
let now_secs = ntp_time.as_secs();
let now_fract_ns = ntp_time.subsec_nanos() as u64;
let now_fract = ((now_fract_ns * u32::MAX as u64) / 1_000_000_000) as u32;
let now = (now_secs as u32) << 16 | (now_fract >> 16);
let rtt = now.checked_sub(delay)?.checked_sub(last_report)?;
let rtt_seconds = rtt >> 16;
let rtt_fraction = (rtt & (u16::MAX as u32)) as f32 / (u16::MAX as u32) as f32;
Some(rtt_seconds as f32 * 1000.0 + rtt_fraction * 1000.0)
}
pub struct NonCryptographicRng;
impl NonCryptographicRng {
#[inline(always)]
pub fn u8() -> u8 {
fastrand::u8(..)
}
#[inline(always)]
pub fn u16() -> u16 {
fastrand::u16(..)
}
#[inline(always)]
pub fn u32() -> u32 {
fastrand::u32(..)
}
#[inline(always)]
pub fn u64() -> u64 {
fastrand::u64(..)
}
#[inline(always)]
pub fn f32() -> f32 {
fastrand::f32()
}
}