use std::time::Duration;
pub trait DurationNumExt: DurationNumExtFallible {
fn seconds(&self) -> Duration {
DurationNumExtFallible::seconds(self).unwrap()
}
fn milliseconds(&self) -> Duration {
DurationNumExtFallible::milliseconds(self).unwrap()
}
fn microseconds(&self) -> Duration {
DurationNumExtFallible::microseconds(self).unwrap()
}
fn nanoseconds(&self) -> Duration {
DurationNumExtFallible::nanoseconds(self).unwrap()
}
fn minutes(&self) -> Duration {
DurationNumExtFallible::minutes(self).unwrap()
}
fn hours(&self) -> Duration {
DurationNumExtFallible::hours(self).unwrap()
}
fn days(&self) -> Duration {
DurationNumExtFallible::days(self).unwrap()
}
}
pub trait DurationNumExtFallible {
fn seconds(&self) -> Option<Duration>;
fn milliseconds(&self) -> Option<Duration>;
fn microseconds(&self) -> Option<Duration>;
fn nanoseconds(&self) -> Option<Duration>;
fn minutes(&self) -> Option<Duration>;
fn hours(&self) -> Option<Duration>;
fn days(&self) -> Option<Duration>;
}
pub const SECS_PER_MINUTE: u64 = 60;
pub const SECS_PER_HOUR: u64 = 60 * 60;
pub const SECS_PER_DAY: u64 = 60 * 60 * 24;
#[cfg(feature = "crate-num")]
mod __num_impl {
use std::time::Duration;
use num::{BigInt, BigUint, ToPrimitive};
use super::{extfn, DurationNumExtFallible, SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MINUTE};
impl DurationNumExtFallible for BigUint {
#[inline]
fn seconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_secs)
}
#[inline]
fn microseconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_micros)
}
#[inline]
fn milliseconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_millis)
}
#[inline]
fn nanoseconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_nanos)
}
#[inline]
fn minutes(&self) -> Option<Duration> {
self.to_u64()
.and_then(|v| v.checked_mul(SECS_PER_MINUTE))
.and_then(extfn::checked_from_secs)
}
#[inline]
fn hours(&self) -> Option<Duration> {
self.to_u64()
.and_then(|v| v.checked_mul(SECS_PER_HOUR))
.and_then(extfn::checked_from_secs)
}
#[inline]
fn days(&self) -> Option<Duration> {
self.to_u64()
.and_then(|v| v.checked_mul(SECS_PER_DAY))
.and_then(extfn::checked_from_secs)
}
}
impl DurationNumExtFallible for BigInt {
#[inline]
fn seconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_secs)
}
#[inline]
fn microseconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_micros)
}
#[inline]
fn milliseconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_millis)
}
#[inline]
fn nanoseconds(&self) -> Option<Duration> {
self.to_u64().and_then(extfn::checked_from_nanos)
}
#[inline]
fn minutes(&self) -> Option<Duration> {
self.to_u64()
.and_then(|v| v.checked_mul(SECS_PER_MINUTE))
.and_then(extfn::checked_from_secs)
}
#[inline]
fn hours(&self) -> Option<Duration> {
self.to_u64()
.and_then(|v| v.checked_mul(SECS_PER_HOUR))
.and_then(extfn::checked_from_secs)
}
#[inline]
fn days(&self) -> Option<Duration> {
self.to_u64()
.and_then(|v| v.checked_mul(SECS_PER_DAY))
.and_then(extfn::checked_from_secs)
}
}
}
mod __std_impl {
use std::time::Duration;
use super::{
extfn, DurationNumExt, DurationNumExtFallible, SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MINUTE,
};
macro_rules! __impl_non_fallible {
($($ty:ty),*) => {
$(__impl_non_fallible!(@$ty);)*
};
(@$ty:ty) => {
impl DurationNumExt for $ty {
#[inline]
fn seconds(&self) -> Duration {
Duration::from_secs(*self as u64)
}
#[inline]
fn microseconds(&self) -> Duration {
Duration::from_micros(*self as u64)
}
#[inline]
fn milliseconds(&self) -> Duration {
Duration::from_millis(*self as u64)
}
#[inline]
fn nanoseconds(&self) -> Duration {
Duration::from_nanos(*self as u64)
}
}
};
}
__impl_non_fallible!(u8, u16, u32, u64);
macro_rules! __impl_fallible_int {
(with-unwrap $($ty:ty),*) => {
$(__impl_fallible_int!(@$ty);)*
$(impl DurationNumExt for $ty {})*
};
($($ty:ty),*) => {
$(__impl_fallible_int!(@$ty);)*
};
(@$ty:ty) => {
impl DurationNumExtFallible for $ty {
#[inline]
fn seconds(&self) -> Option<Duration> {
(*self).try_into().ok().and_then(extfn::checked_from_secs)
}
#[inline]
fn microseconds(&self) -> Option<Duration> {
(*self).try_into().ok().and_then(extfn::checked_from_micros)
}
#[inline]
fn milliseconds(&self) -> Option<Duration> {
(*self).try_into().ok().and_then(extfn::checked_from_millis)
}
#[inline]
fn nanoseconds(&self) -> Option<Duration> {
(*self).try_into().ok().and_then(extfn::checked_from_nanos)
}
#[inline]
fn minutes(&self) -> Option<Duration> {
(*self)
.try_into()
.ok()
.and_then(|e: u64| e.checked_mul(SECS_PER_MINUTE))
.and_then(extfn::checked_from_secs)
}
#[inline]
fn hours(&self) -> Option<Duration> {
(*self)
.try_into()
.ok()
.and_then(|e: u64| e.checked_mul(SECS_PER_HOUR))
.and_then(extfn::checked_from_secs)
}
#[inline]
fn days(&self) -> Option<Duration> {
(*self)
.try_into()
.ok()
.and_then(|e: u64| e.checked_mul(SECS_PER_DAY))
.and_then(extfn::checked_from_secs)
}
}
};
}
__impl_fallible_int!(with-unwrap i8, i16, i32, i64, i128, u128);
__impl_fallible_int!(u8, u16, u32, u64);
macro_rules! __impl_fallible_float {
($($ty:ty: $ident:ident),*) => {
$(__impl_fallible_float!(@$ty, $ident);)*
};
(@$ty:ty, $ident:ident) => {
impl DurationNumExtFallible for $ty {
#[inline]
fn seconds(&self) -> Option<Duration> {
Duration::$ident(*self).ok()
}
#[inline]
fn microseconds(&self) -> Option<Duration> {
Duration::$ident(*self / 1_000_000.0).ok()
}
#[inline]
fn milliseconds(&self) -> Option<Duration> {
Duration::$ident(*self / 1_000.0).ok()
}
#[inline]
fn nanoseconds(&self) -> Option<Duration> {
Duration::$ident(*self / 1_000_000_000.0).ok()
}
#[inline]
fn minutes(&self) -> Option<Duration> {
Duration::$ident(*self * 60.0).ok()
}
#[inline]
fn hours(&self) -> Option<Duration> {
Duration::$ident(*self * 3600.0).ok()
}
#[inline]
fn days(&self) -> Option<Duration> {
Duration::$ident(*self * 86400.0).ok()
}
}
impl DurationNumExt for $ty {}
};
}
__impl_fallible_float!(f32: try_from_secs_f32, f64: try_from_secs_f64);
}
pub const NANOS_PER_SEC: u32 = 1_000_000_000;
pub const NANOS_PER_MILLI: u32 = 1_000_000;
pub const NANOS_PER_MICRO: u32 = 1_000;
pub const MILLIS_PER_SEC: u64 = 1_000;
pub const MICROS_PER_SEC: u64 = 1_000_000;
pub mod extfn {
use std::time::Duration;
use super::{MICROS_PER_SEC, MILLIS_PER_SEC, NANOS_PER_MICRO, NANOS_PER_MILLI, NANOS_PER_SEC};
pub fn checked_from_secs(secs: u64) -> Option<Duration> {
checked_new(secs, 0)
}
pub fn checked_from_millis(millis: u64) -> Option<Duration> {
millis
.checked_div(MILLIS_PER_SEC)
.zip(
millis
.checked_rem(MILLIS_PER_SEC)
.and_then(|r| <u64 as TryInto<u32>>::try_into(r).ok())
.and_then(|r| r.checked_mul(NANOS_PER_MILLI)),
)
.and_then(|(x, y)| checked_new(x, y))
}
pub fn checked_from_micros(micros: u64) -> Option<Duration> {
micros
.checked_div(MICROS_PER_SEC)
.zip(
micros
.checked_rem(MICROS_PER_SEC)
.and_then(|r| <u64 as TryInto<u32>>::try_into(r).ok())
.and_then(|r| r.checked_mul(NANOS_PER_MICRO)),
)
.and_then(|(x, y)| checked_new(x, y))
}
pub fn checked_from_nanos(nanos: u64) -> Option<Duration> {
nanos
.checked_div(NANOS_PER_SEC as u64)
.zip(
nanos
.checked_rem(NANOS_PER_SEC as u64)
.and_then(|r| <u64 as TryInto<u32>>::try_into(r).ok()),
)
.and_then(|(x, y)| checked_new(x, y))
}
pub fn checked_new(secs: u64, nanos: u32) -> Option<Duration> {
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
Some(secs) => secs,
None => return None,
};
let nanos = nanos % NANOS_PER_SEC;
Some(Duration::new(secs, nanos))
}
}
pub trait DurationExt {}