1 | //! Conversion between units of time. |
2 | |
3 | use self::sealed::Per; |
4 | |
5 | mod sealed { |
6 | /// A trait for defining the ratio of two units of time. |
7 | /// |
8 | /// This trait is used to implement the `per` method on the various structs. |
9 | pub trait Per<T> { |
10 | /// The smallest unsigned integer type that can represent [`VALUE`](Self::VALUE). |
11 | type Output; |
12 | |
13 | /// The number of one unit of time in the other. |
14 | const VALUE: Self::Output; |
15 | } |
16 | } |
17 | |
18 | /// Declare and implement `Per` for all relevant types. Identity implementations are automatic. |
19 | macro_rules! impl_per { |
20 | ($($t:ident ($str:literal) per {$( |
21 | $larger:ident : $output:ty = $value:expr |
22 | )*})*) => {$( |
23 | #[doc = concat!("A unit of time representing exactly one " , $str, "." )] |
24 | #[derive(Debug, Clone, Copy)] |
25 | pub struct $t; |
26 | |
27 | impl $t { |
28 | #[doc = concat!("Obtain the number of times `" , stringify!($t), "` can fit into `T`." )] |
29 | #[doc = concat!("If `T` is smaller than `" , stringify!($t), "`, the code will fail to" )] |
30 | /// compile. The return type is the smallest unsigned integer type that can represent |
31 | /// the value. |
32 | /// |
33 | /// Valid calls: |
34 | /// |
35 | #[doc = concat!(" - `" , stringify!($t), "::per(" , stringify!($t), ")` (returns `u8`)" )] |
36 | $(#[doc = concat!(" - `" , stringify!($t), "::per(" , stringify!($larger), ")` (returns `" , stringify!($output), "`)" )])* |
37 | pub const fn per<T>(_larger: T) -> <Self as Per<T>>::Output |
38 | where |
39 | Self: Per<T>, |
40 | T: Copy, |
41 | { |
42 | Self::VALUE |
43 | } |
44 | } |
45 | |
46 | impl Per<$t> for $t { |
47 | type Output = u8; |
48 | |
49 | const VALUE: u8 = 1; |
50 | } |
51 | |
52 | $(impl Per<$larger> for $t { |
53 | type Output = $output; |
54 | |
55 | const VALUE: $output = $value; |
56 | })* |
57 | )*}; |
58 | } |
59 | |
60 | impl_per! { |
61 | Nanosecond ("nanosecond" ) per { |
62 | Microsecond: u16 = 1_000 |
63 | Millisecond: u32 = 1_000_000 |
64 | Second: u32 = 1_000_000_000 |
65 | Minute: u64 = 60_000_000_000 |
66 | Hour: u64 = 3_600_000_000_000 |
67 | Day: u64 = 86_400_000_000_000 |
68 | Week: u64 = 604_800_000_000_000 |
69 | } |
70 | Microsecond ("microsecond" ) per { |
71 | Millisecond: u16 = 1_000 |
72 | Second: u32 = 1_000_000 |
73 | Minute: u32 = 60_000_000 |
74 | Hour: u32 = 3_600_000_000 |
75 | Day: u64 = 86_400_000_000 |
76 | Week: u64 = 604_800_000_000 |
77 | } |
78 | Millisecond ("millisecond" ) per { |
79 | Second: u16 = 1_000 |
80 | Minute: u16 = 60_000 |
81 | Hour: u32 = 3_600_000 |
82 | Day: u32 = 86_400_000 |
83 | Week: u32 = 604_800_000 |
84 | } |
85 | Second ("second" ) per { |
86 | Minute: u8 = 60 |
87 | Hour: u16 = 3_600 |
88 | Day: u32 = 86_400 |
89 | Week: u32 = 604_800 |
90 | } |
91 | Minute ("minute" ) per { |
92 | Hour: u8 = 60 |
93 | Day: u16 = 1_440 |
94 | Week: u16 = 10_080 |
95 | } |
96 | Hour ("hour" ) per { |
97 | Day: u8 = 24 |
98 | Week: u8 = 168 |
99 | } |
100 | Day ("day" ) per { |
101 | Week: u8 = 7 |
102 | } |
103 | Week ("week" ) per {} |
104 | } |
105 | |