Revision control

Copy as Markdown

Other Tools

//! Conversion between units of time.
use self::sealed::Per;
mod sealed {
/// A trait for defining the ratio of two units of time.
///
/// This trait is used to implement the `per` method on the various structs.
pub trait Per<T> {
/// The smallest unsigned integer type that can represent [`VALUE`](Self::VALUE).
type Output;
/// The number of one unit of time in the other.
const VALUE: Self::Output;
}
}
/// Declare and implement `Per` for all relevant types. Identity implementations are automatic.
macro_rules! impl_per {
($($t:ident ($str:literal) per {$(
$larger:ident : $output:ty = $value:expr
)*})*) => {$(
#[doc = concat!("A unit of time representing exactly one ", $str, ".")]
#[derive(Debug, Clone, Copy)]
pub struct $t;
impl $t {
#[doc = concat!("Obtain the number of times `", stringify!($t), "` can fit into `T`.")]
#[doc = concat!("If `T` is smaller than `", stringify!($t), "`, the code will fail to")]
/// compile. The return type is the smallest unsigned integer type that can represent
/// the value.
///
/// Valid calls:
///
#[doc = concat!(" - `", stringify!($t), "::per(", stringify!($t), ")` (returns `u8`)")]
$(#[doc = concat!(" - `", stringify!($t), "::per(", stringify!($larger), ")` (returns `", stringify!($output), "`)")])*
pub const fn per<T>(_larger: T) -> <Self as Per<T>>::Output
where
Self: Per<T>,
T: Copy,
{
Self::VALUE
}
}
impl Per<$t> for $t {
type Output = u8;
const VALUE: u8 = 1;
}
$(impl Per<$larger> for $t {
type Output = $output;
const VALUE: $output = $value;
})*
)*};
}
impl_per! {
Nanosecond ("nanosecond") per {
Microsecond: u16 = 1_000
Millisecond: u32 = 1_000_000
Second: u32 = 1_000_000_000
Minute: u64 = 60_000_000_000
Hour: u64 = 3_600_000_000_000
Day: u64 = 86_400_000_000_000
Week: u64 = 604_800_000_000_000
}
Microsecond ("microsecond") per {
Millisecond: u16 = 1_000
Second: u32 = 1_000_000
Minute: u32 = 60_000_000
Hour: u32 = 3_600_000_000
Day: u64 = 86_400_000_000
Week: u64 = 604_800_000_000
}
Millisecond ("millisecond") per {
Second: u16 = 1_000
Minute: u16 = 60_000
Hour: u32 = 3_600_000
Day: u32 = 86_400_000
Week: u32 = 604_800_000
}
Second ("second") per {
Minute: u8 = 60
Hour: u16 = 3_600
Day: u32 = 86_400
Week: u32 = 604_800
}
Minute ("minute") per {
Hour: u8 = 60
Day: u16 = 1_440
Week: u16 = 10_080
}
Hour ("hour") per {
Day: u8 = 24
Week: u8 = 168
}
Day ("day") per {
Week: u8 = 7
}
Week ("week") per {}
}