//! 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 { /// 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(_larger: T) -> >::Output where Self: Per, 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 {} }