use core::time::Duration as StdDuration;
use num_conv::prelude::*;
use crate::convert::*;
use crate::Duration;
mod sealed {
pub trait Sealed {}
impl Sealed for i64 {}
impl Sealed for u64 {}
impl Sealed for f64 {}
}
pub trait NumericalDuration: sealed::Sealed {
fn nanoseconds(self) -> Duration;
fn microseconds(self) -> Duration;
fn milliseconds(self) -> Duration;
fn seconds(self) -> Duration;
fn minutes(self) -> Duration;
fn hours(self) -> Duration;
fn days(self) -> Duration;
fn weeks(self) -> Duration;
}
impl NumericalDuration for i64 {
fn nanoseconds(self) -> Duration {
Duration::nanoseconds(self)
}
fn microseconds(self) -> Duration {
Duration::microseconds(self)
}
fn milliseconds(self) -> Duration {
Duration::milliseconds(self)
}
fn seconds(self) -> Duration {
Duration::seconds(self)
}
fn minutes(self) -> Duration {
Duration::minutes(self)
}
fn hours(self) -> Duration {
Duration::hours(self)
}
fn days(self) -> Duration {
Duration::days(self)
}
fn weeks(self) -> Duration {
Duration::weeks(self)
}
}
impl NumericalDuration for f64 {
fn nanoseconds(self) -> Duration {
Duration::nanoseconds(self as _)
}
fn microseconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Microsecond) as Self) as _)
}
fn milliseconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Millisecond) as Self) as _)
}
fn seconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Second) as Self) as _)
}
fn minutes(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Minute) as Self) as _)
}
fn hours(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Hour) as Self) as _)
}
fn days(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Day) as Self) as _)
}
fn weeks(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Week) as Self) as _)
}
}
pub trait NumericalStdDuration: sealed::Sealed {
fn std_nanoseconds(self) -> StdDuration;
fn std_microseconds(self) -> StdDuration;
fn std_milliseconds(self) -> StdDuration;
fn std_seconds(self) -> StdDuration;
fn std_minutes(self) -> StdDuration;
fn std_hours(self) -> StdDuration;
fn std_days(self) -> StdDuration;
fn std_weeks(self) -> StdDuration;
}
impl NumericalStdDuration for u64 {
fn std_nanoseconds(self) -> StdDuration {
StdDuration::from_nanos(self)
}
fn std_microseconds(self) -> StdDuration {
StdDuration::from_micros(self)
}
fn std_milliseconds(self) -> StdDuration {
StdDuration::from_millis(self)
}
fn std_seconds(self) -> StdDuration {
StdDuration::from_secs(self)
}
fn std_minutes(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Minute).extend())
.expect("overflow constructing `time::Duration`"),
)
}
fn std_hours(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Hour).extend())
.expect("overflow constructing `time::Duration`"),
)
}
fn std_days(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Day).extend())
.expect("overflow constructing `time::Duration`"),
)
}
fn std_weeks(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Week).extend())
.expect("overflow constructing `time::Duration`"),
)
}
}
impl NumericalStdDuration for f64 {
fn std_nanoseconds(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos(self as _)
}
fn std_microseconds(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos((self * Nanosecond::per(Microsecond) as Self) as _)
}
fn std_milliseconds(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos((self * Nanosecond::per(Millisecond) as Self) as _)
}
fn std_seconds(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos((self * Nanosecond::per(Second) as Self) as _)
}
fn std_minutes(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos((self * Nanosecond::per(Minute) as Self) as _)
}
fn std_hours(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos((self * Nanosecond::per(Hour) as Self) as _)
}
fn std_days(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos((self * Nanosecond::per(Day) as Self) as _)
}
fn std_weeks(self) -> StdDuration {
assert!(self >= 0.);
StdDuration::from_nanos((self * Nanosecond::per(Week) as Self) as _)
}
}
pub(crate) trait DigitCount {
fn num_digits(self) -> u8;
}
macro_rules! impl_digit_count {
($($t:ty),* $(,)?) => {
$(impl DigitCount for $t {
fn num_digits(self) -> u8 {
match self.checked_ilog10() {
Some(n) => n.truncate::<u8>() + 1,
None => 1,
}
}
})*
};
}
impl_digit_count!(u8, u16, u32);