use core::{
ops::{Add, Sub},
cmp::{Ord, PartialOrd, Ordering},
fmt::{self, Debug},
};
use crate::{
kty::{timespec, time_t, k_long},
result::{Result},
util::int::{Int},
};
use std::fmt::Formatter;
pub mod clock;
pub mod timer;
pub fn time_from_timespec(t: timespec) -> Time {
Time {
seconds: t.tv_sec as i64,
nanoseconds: t.tv_nsec as i64,
}
}
pub fn time_to_timespec(d: Time) -> timespec {
timespec {
tv_sec: d.seconds as time_t,
tv_nsec: d.nanoseconds as k_long,
}
}
const NANOS_PER_SEC: i64 = 1_000_000_000;
const NANOS_PER_MILLI: i64 = 1_000_000;
const NANOS_PER_MICRO: i64 = 1_000;
const MICROS_PER_SEC: i64 = 1_000_000;
const MILLIS_PER_SEC: i64 = 1_000;
const SECS_PER_MIN: i64 = 60;
const SECS_PER_HOUR: i64 = 60 * SECS_PER_MIN;
const SECS_PER_DAY: i64 = 24 * SECS_PER_HOUR;
#[derive(Pod, Copy, Clone, PartialEq, Eq)]
pub struct Time {
pub seconds: i64,
pub nanoseconds: i64,
}
impl Time {
pub fn normalize(self) -> Time {
let (mut sec, mut nano) = self.nanoseconds.div_rem(NANOS_PER_SEC);
if nano < 0 {
sec -= 1;
nano += NANOS_PER_SEC;
}
Time { seconds: self.seconds.saturating_add(sec), nanoseconds: nano }
}
pub fn nanoseconds(n: i64) -> Time {
let (s, n) = n.div_rem(NANOS_PER_SEC);
Time { seconds: s, nanoseconds: n }
}
pub fn microseconds(m: i64) -> Time {
let (s, m) = m.div_rem(MICROS_PER_SEC);
Time { seconds: s, nanoseconds: m * NANOS_PER_MICRO }
}
pub fn milliseconds(m: i64) -> Time {
let (s, m) = m.div_rem(MILLIS_PER_SEC);
Time { seconds: s, nanoseconds: m * NANOS_PER_MILLI }
}
pub fn seconds(s: i64) -> Time {
Time { seconds: s, nanoseconds: 0 }
}
pub fn minutes(m: i64) -> Time {
Time::seconds(m.wrapping_mul(SECS_PER_MIN))
}
pub fn hours(h: i64) -> Time {
Time::seconds(h.wrapping_mul(SECS_PER_HOUR))
}
pub fn days(d: i64) -> Time {
Time::seconds(d.wrapping_mul(SECS_PER_DAY))
}
}
impl Debug for Time {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let time = self.normalize();
core::write!(f, "\"{}s {}ns\"", time.seconds, time.nanoseconds)
}
}
impl Add for Time {
type Output = Time;
fn add(self, other: Time) -> Time {
let one = self.normalize();
let two = other.normalize();
let time = Time {
seconds: one.seconds.saturating_add(two.seconds),
nanoseconds: one.nanoseconds + two.nanoseconds,
};
time.normalize()
}
}
impl Sub for Time {
type Output = Time;
fn sub(self, other: Time) -> Time {
let one = self.normalize();
let two = other.normalize();
let time = Time {
seconds: one.seconds.saturating_sub(two.seconds),
nanoseconds: one.nanoseconds - two.nanoseconds,
};
time.normalize()
}
}
impl PartialOrd for Time {
fn partial_cmp(&self, other: &Time) -> Option<Ordering> {
Some(self.cmp(&other))
}
}
impl Ord for Time {
fn cmp(&self, other: &Time) -> Ordering {
let one = self.normalize();
let two = other.normalize();
(one.seconds, one.nanoseconds).cmp(&(two.seconds, two.nanoseconds))
}
}