#![cfg_attr(not(feature = "std"), no_std)]
use core::ops::{Add, Sub};
use core::time;
#[cfg(feature = "std")]
mod std_time;
#[cfg(feature = "std")]
pub use std_time::*;
const fn seconds_to_micros(seconds: u64) -> u64 {
seconds * 1_000_000
}
const fn millis_to_micros(millis: u64) -> u64 {
millis * 1_000
}
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)]
pub struct MonotonicTime {
micros: u64,
}
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)]
pub struct RealTime {
micros: u64,
}
macro_rules! time_math_impl {
($time_type:ty) => {
impl $time_type {
pub const ZERO: Self = Self { micros: 0 };
pub const fn from_micros(micros: u64) -> Self {
Self { micros }
}
pub const fn as_micros(&self) -> u64 {
self.micros
}
pub const fn from_millis(millis: u64) -> Self {
Self {
micros: millis_to_micros(millis),
}
}
pub const fn from_seconds(seconds: u32) -> Self {
Self {
micros: seconds_to_micros(seconds as u64),
}
}
}
impl Sub for $time_type {
type Output = Duration;
fn sub(self, rhs: Self) -> Self::Output {
Duration::from_micros(self.micros - rhs.micros)
}
}
impl Add<time::Duration> for $time_type {
type Output = Self;
fn add(self, other: time::Duration) -> Self {
let mo: u64 = other.as_micros().try_into().unwrap();
Self {
micros: self.micros + mo,
}
}
}
impl Add<Duration> for $time_type {
type Output = Self;
fn add(self, other: Duration) -> Self {
Self {
micros: self.micros + other.micros,
}
}
}
};
}
time_math_impl! {MonotonicTime}
time_math_impl! {RealTime}
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)]
pub struct Duration {
micros: u64,
}
impl Duration {
pub const fn from_micros(micros: u64) -> Self {
Duration { micros }
}
pub const fn from_seconds(seconds: u64) -> Self {
Duration {
micros: seconds_to_micros(seconds),
}
}
pub const fn from_milliseconds(millis: u64) -> Self {
Duration {
micros: millis_to_micros(millis),
}
}
}
impl Add for Duration {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
micros: self.micros + rhs.micros,
}
}
}
impl Sub for Duration {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
micros: self.micros - rhs.micros,
}
}
}
fn duration_from_micros(micros: u64) -> time::Duration {
let secs = micros / 1_000_000;
let sub_micros = (micros % 1_000_000) as u32;
let sub_nsec = sub_micros * 1000;
time::Duration::new(secs, sub_nsec)
}
const fn micros_from_duration(duration: time::Duration) -> u64 {
duration.as_secs() * 1_000_000 + duration.subsec_micros() as u64
}
impl MonotonicTime {
pub fn to_core_duration(self) -> core::time::Duration {
duration_from_micros(self.micros)
}
pub fn from_core_duration(ctd: core::time::Duration) -> Self {
Self::from_micros(micros_from_duration(ctd))
}
}