use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
use std::time::Duration;
use super::op_err;
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
pub struct MicroSeconds(pub u64);
impl MicroSeconds {
pub const INVALID: Self = Self(capi::PA_USEC_INVALID);
pub const SECOND: Self = Self(super::MICROS_PER_SEC);
pub const MILLISECOND: Self = Self(super::MICROS_PER_MILLI);
pub const ZERO: Self = Self(0);
pub const MIN: Self = Self(0);
pub const MAX: Self = Self(capi::PA_USEC_MAX);
#[inline]
pub const fn inner(&self) -> u64 {
self.0
}
#[inline]
pub const fn is_valid(&self) -> bool {
self.0 != Self::INVALID.0
}
#[inline]
pub const fn is_zero(&self) -> bool {
self.0 == 0
}
#[inline]
pub fn from_secs(secs: u64) -> Option<Self> {
secs.checked_mul(super::MICROS_PER_SEC).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn from_millis(millis: u64) -> Option<Self> {
millis.checked_mul(super::MICROS_PER_MILLI).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn diff(self, other: Self) -> Self {
match self >= other {
true => Self(self.0 - other.0),
false => Self(other.0 - self.0),
}
}
#[inline]
pub const fn as_secs(&self) -> u64 {
self.0 / super::MICROS_PER_SEC
}
#[inline]
pub const fn as_millis(&self) -> u64 {
self.0 / super::MICROS_PER_MILLI
}
#[inline]
pub fn from_secs_f64(secs: f64) -> Self {
let duration = Duration::from_secs_f64(secs);
Self::try_from(duration).expect("overflow during microseconds conversion")
}
#[inline]
pub fn from_secs_f32(secs: f32) -> Self {
let duration = Duration::from_secs_f32(secs);
Self::try_from(duration).expect("overflow during microseconds conversion")
}
#[inline]
pub fn as_secs_f64(&self) -> f64 {
(self.0 as f64) / (super::MICROS_PER_SEC as f64)
}
#[inline]
pub fn as_secs_f32(&self) -> f32 {
(self.0 as f32) / (super::MICROS_PER_SEC as f32)
}
#[inline]
pub fn checked_add(self, other: Self) -> Option<Self> {
self.0.checked_add(other.0).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn checked_add_duration(self, rhs: Duration) -> Option<Self> {
let usecs = Self::try_from(rhs).ok()?;
self.0.checked_add(usecs.0).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn checked_sub(self, other: Self) -> Option<Self> {
self.0.checked_sub(other.0).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn checked_sub_duration(self, rhs: Duration) -> Option<Self> {
let usecs = Self::try_from(rhs).ok()?;
self.0.checked_sub(usecs.0).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn checked_mul(self, rhs: u32) -> Option<Self> {
self.0.checked_mul(rhs as u64).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn checked_div(self, rhs: u32) -> Option<Self> {
self.0.checked_div(rhs as u64).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn checked_rem(self, rhs: u32) -> Option<Self> {
self.0.checked_rem(rhs as u64).and_then(|i| Some(Self(i)))
}
#[inline]
pub fn mul_f64(self, rhs: f64) -> Self {
Self::from_secs_f64(rhs * self.as_secs_f64())
}
#[inline]
pub fn mul_f32(self, rhs: f32) -> Self {
Self::from_secs_f32(rhs * self.as_secs_f32())
}
#[inline]
pub fn div_f64(self, rhs: f64) -> Self {
Self::from_secs_f64(self.as_secs_f64() / rhs)
}
#[inline]
pub fn div_f32(self, rhs: f32) -> Self {
Self::from_secs_f32(self.as_secs_f32() / rhs)
}
}
impl std::fmt::Display for MicroSeconds {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{} µs", self.0)
}
}
impl Add for MicroSeconds {
type Output = Self;
#[track_caller]
#[inline]
fn add(self, other: Self) -> Self {
self.checked_add(other).expect(op_err::ADD)
}
}
impl AddAssign for MicroSeconds {
#[track_caller]
#[inline]
fn add_assign(&mut self, rhs: Self) {
*self = self.add(rhs);
}
}
impl Sub for MicroSeconds {
type Output = Self;
#[track_caller]
#[inline]
fn sub(self, other: Self) -> Self {
self.checked_sub(other).expect(op_err::SUB)
}
}
impl SubAssign for MicroSeconds {
#[track_caller]
#[inline]
fn sub_assign(&mut self, rhs: Self) {
*self = self.sub(rhs);
}
}
impl Add<Duration> for MicroSeconds {
type Output = Self;
#[track_caller]
#[inline]
fn add(self, rhs: Duration) -> Self {
self.checked_add_duration(rhs).expect(op_err::ADD)
}
}
impl AddAssign<Duration> for MicroSeconds {
#[track_caller]
#[inline]
fn add_assign(&mut self, rhs: Duration) {
*self = self.add(rhs);
}
}
impl Add<MicroSeconds> for Duration {
type Output = Self;
#[track_caller]
#[inline]
fn add(self, rhs: MicroSeconds) -> Self {
self.checked_add(Duration::from_micros(rhs.0)).expect(op_err::ADD)
}
}
impl AddAssign<MicroSeconds> for Duration {
#[track_caller]
#[inline]
fn add_assign(&mut self, rhs: MicroSeconds) {
*self = self.add(rhs);
}
}
impl Sub<Duration> for MicroSeconds {
type Output = Self;
#[track_caller]
#[inline]
fn sub(self, rhs: Duration) -> Self {
self.checked_sub_duration(rhs).expect(op_err::SUB)
}
}
impl SubAssign<Duration> for MicroSeconds {
#[track_caller]
#[inline]
fn sub_assign(&mut self, rhs: Duration) {
*self = self.sub(rhs);
}
}
impl Sub<MicroSeconds> for Duration {
type Output = Self;
#[track_caller]
#[inline]
fn sub(self, rhs: MicroSeconds) -> Self {
self.checked_sub(Duration::from_micros(rhs.0)).expect(op_err::SUB)
}
}
impl SubAssign<MicroSeconds> for Duration {
#[track_caller]
#[inline]
fn sub_assign(&mut self, rhs: MicroSeconds) {
*self = self.sub(rhs);
}
}
impl Mul<u32> for MicroSeconds {
type Output = Self;
#[track_caller]
#[inline]
fn mul(self, rhs: u32) -> Self {
Self(self.0.checked_mul(rhs as u64).expect(op_err::MUL))
}
}
impl MulAssign<u32> for MicroSeconds {
#[track_caller]
#[inline]
fn mul_assign(&mut self, rhs: u32) {
*self = self.mul(rhs);
}
}
impl Mul<MicroSeconds> for u32 {
type Output = MicroSeconds;
#[track_caller]
#[inline]
fn mul(self, rhs: MicroSeconds) -> MicroSeconds {
rhs.mul(self)
}
}
impl Div<u32> for MicroSeconds {
type Output = Self;
#[track_caller]
#[inline]
fn div(self, rhs: u32) -> Self {
Self(self.0.checked_div(rhs as u64).expect(op_err::DIV))
}
}
impl DivAssign<u32> for MicroSeconds {
#[track_caller]
#[inline]
fn div_assign(&mut self, rhs: u32) {
*self = self.div(rhs);
}
}
impl Rem<u32> for MicroSeconds {
type Output = Self;
#[track_caller]
#[inline]
fn rem(self, rhs: u32) -> Self {
Self(self.0.checked_rem(rhs as u64).expect(op_err::REM))
}
}
impl RemAssign<u32> for MicroSeconds {
#[track_caller]
#[inline]
fn rem_assign(&mut self, rhs: u32) {
*self = self.rem(rhs);
}
}