Skip to main content

time_core/
convert.rs

1//! Conversion between units of time.
2
3use self::sealed::{DefaultOutput, MultipleOf};
4
5mod 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    #[diagnostic::on_unimplemented(message = "`{Self}` is not an integer multiple of `{T}`")]
10    pub trait MultipleOf<T, Output> {
11        /// The number of one unit of time in the other.
12        const VALUE: Output;
13    }
14
15    /// A trait for defining the default output type for the `per` method.
16    pub trait DefaultOutput<T> {
17        /// The default output type for the `per` method.
18        type Output;
19    }
20}
21
22/// Given the list of types, stringify them as a list.
23macro_rules! stringify_outputs {
24    (@inner $first:ty) => {
25        concat!("or `", stringify!($first), "`")
26    };
27    (@inner $first:ty, $($t:ty),+) => {
28        concat!(stringify_outputs!($first), ", ", stringify_outputs!(@inner $($t),+))
29    };
30    ($first:ty) => {
31        concat!("`", stringify!($first), "`")
32    };
33    ($($t:ty),+) => {
34        stringify_outputs!(@inner $($t),+)
35    };
36}
37
38// Split this out to a separate function to permit naming `T` while also using `impl Trait` as a
39// parameter in the public API.`
40const fn multiple_of_value<T, U, Output>(_: T) -> Output
41where
42    T: MultipleOf<U, Output> + Copy,
43{
44    T::VALUE
45}
46
47/// Declare and implement `Per` for all relevant types. Identity implementations are automatic.
48macro_rules! impl_per {
49    ($($t:ident ($str:literal) per {$(
50        $larger:ident : [$default_output:ty]
51
52        $($int_output:ty)|+ = $int_value:expr;
53        $($float_output:ty)|+ = $float_value:expr;
54    )+})*) => {$(
55        #[doc = concat!("A unit of time representing exactly one ", $str, ".")]
56        #[derive(Debug, Clone, Copy)]
57        pub struct $t;
58
59        impl $t {
60            #[doc = concat!("Obtain the number of times `", stringify!($t), "` can fit into `T`.")]
61            #[doc = concat!("If `T` is smaller than `", stringify!($t), "`, the code will fail to")]
62            /// compile. The return type is the smallest unsigned integer type that can represent
63            /// the value.
64            ///
65            /// Valid calls:
66            ///
67            $(#[doc = concat!(
68                "  - `", stringify!($t), "::per(", stringify!($larger), ")` (returns `",
69                stringify!($default_output), "`)"
70            )])+
71            #[inline]
72            pub const fn per<T>(_larger: T) -> <T as DefaultOutput<Self>>::Output
73            where
74                T: MultipleOf<Self, T::Output> + DefaultOutput<Self> + Copy,
75            {
76                T::VALUE
77            }
78
79            #[doc = concat!("Obtain the number of times `", stringify!($t), "` can fit into `T`.")]
80            #[doc = concat!("If `T` is smaller than `", stringify!($t), "`, the code will fail to")]
81            /// compile. The return type is any primitive numeric type that can represent the value.
82            ///
83            /// Valid calls:
84            ///
85            $(#[doc = concat!(
86                "  - `", stringify!($t), "::per(", stringify!($larger), ")` (returns ",
87                stringify_outputs!($($int_output),+ , $($float_output),+), ")"
88            )])+
89            #[inline]
90            pub const fn per_t<Output>(larger: impl MultipleOf<Self, Output> + Copy) -> Output {
91                multiple_of_value(larger)
92            }
93        }
94
95        $(
96            $(impl MultipleOf<$t, $int_output> for $larger {
97                const VALUE: $int_output = $int_value;
98            })+
99
100            $(impl MultipleOf<$t, $float_output> for $larger {
101                const VALUE: $float_output = $float_value;
102            })+
103
104            impl DefaultOutput<$t> for $larger {
105                type Output = $default_output;
106            }
107        )+
108    )*};
109}
110
111#[automatically_derived]
impl ::core::fmt::Debug for Week {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Week")
    }
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Week { }
#[automatically_derived]
impl ::core::clone::Clone for Week {
    #[inline]
    fn clone(&self) -> Week { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for Week { }
impl Week {
    #[doc = "Obtain the number of times `Week` can fit into `T`."]
    #[doc = "If `T` is smaller than `Week`, the code will fail to"]
    /// compile. The return type is the smallest unsigned integer type that can represent
    /// the value.
    ///
    /// Valid calls:
    ///
    #[doc = "  - `Week::per(Week)` (returns `u8`)"]
    #[inline]
    pub const fn per<T>(_larger: T) -> <T as DefaultOutput<Self>>::Output
        where T: MultipleOf<Self, T::Output> + DefaultOutput<Self> + Copy {
        T::VALUE
    }
    #[doc = "Obtain the number of times `Week` can fit into `T`."]
    #[doc = "If `T` is smaller than `Week`, the code will fail to"]
    /// compile. The return type is any primitive numeric type that can represent the value.
    ///
    /// Valid calls:
    ///
    #[doc =
    "  - `Week::per(Week)` (returns `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `f32`, or `f64`)"]
    #[inline]
    pub const fn per_t<Output>(larger: impl MultipleOf<Self, Output> + Copy)
        -> Output {
        multiple_of_value(larger)
    }
}
impl MultipleOf<Week, u8> for Week {
    const VALUE: u8 = 1;
}
impl MultipleOf<Week, u16> for Week {
    const VALUE: u16 = 1;
}
impl MultipleOf<Week, u32> for Week {
    const VALUE: u32 = 1;
}
impl MultipleOf<Week, u64> for Week {
    const VALUE: u64 = 1;
}
impl MultipleOf<Week, u128> for Week {
    const VALUE: u128 = 1;
}
impl MultipleOf<Week, usize> for Week {
    const VALUE: usize = 1;
}
impl MultipleOf<Week, i8> for Week {
    const VALUE: i8 = 1;
}
impl MultipleOf<Week, i16> for Week {
    const VALUE: i16 = 1;
}
impl MultipleOf<Week, i32> for Week {
    const VALUE: i32 = 1;
}
impl MultipleOf<Week, i64> for Week {
    const VALUE: i64 = 1;
}
impl MultipleOf<Week, i128> for Week {
    const VALUE: i128 = 1;
}
impl MultipleOf<Week, isize> for Week {
    const VALUE: isize = 1;
}
impl MultipleOf<Week, f32> for Week {
    const VALUE: f32 = 1.;
}
impl MultipleOf<Week, f64> for Week {
    const VALUE: f64 = 1.;
}
impl DefaultOutput<Week> for Week {
    type Output = u8;
}impl_per! {
112    Nanosecond ("nanosecond") per {
113        Nanosecond: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
114        Microsecond: [u16] u16|u32|u64|u128|usize|i16|i32|i64|i128|isize = 1_000; f32|f64 = 1_000.;
115        Millisecond: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 1_000_000; f32|f64 = 1_000_000.;
116        Second:
117            [u32] u32|u64|u128|usize|i32|i64|i128|isize = 1_000_000_000; f32|f64 = 1_000_000_000.;
118        Minute: [u64] u64|u128|i64|i128 = 60_000_000_000; f32|f64 = 60_000_000_000.;
119        Hour: [u64] u64|u128|i64|i128 = 3_600_000_000_000; f32|f64 = 3_600_000_000_000.;
120        Day: [u64] u64|u128|i64|i128 = 86_400_000_000_000; f32|f64 = 86_400_000_000_000.;
121        Week: [u64] u64|u128|i64|i128 = 604_800_000_000_000; f32|f64 = 604_800_000_000_000.;
122    }
123    Microsecond ("microsecond") per {
124        Microsecond: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
125        Millisecond: [u16] u16|u32|u64|u128|usize|i16|i32|i64|i128|isize = 1_000; f32|f64 = 1_000.;
126        Second: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 1_000_000; f32|f64 = 1_000_000.;
127        Minute: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 60_000_000; f32|f64 = 60_000_000.;
128        Hour: [u32] u32|u64|u128|i64|i128 = 3_600_000_000; f32|f64 = 3_600_000_000.;
129        Day: [u64] u64|u128|i64|i128 = 86_400_000_000; f32|f64 = 86_400_000_000.;
130        Week: [u64] u64|u128|i64|i128 = 604_800_000_000; f32|f64 = 604_800_000_000.;
131    }
132    Millisecond ("millisecond") per {
133        Millisecond: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
134        Second: [u16] u16|u32|u64|u128|usize|i16|i32|i64|i128|isize = 1_000; f32|f64 = 1_000.;
135        Minute: [u16] u16|u32|u64|u128|usize|i32|i64|i128|isize = 60_000; f32|f64 = 60_000.;
136        Hour: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 3_600_000; f32|f64 = 3_600_000.;
137        Day: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 86_400_000; f32|f64 = 86_400_000.;
138        Week: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 604_800_000; f32|f64 = 604_800_000.;
139    }
140    Second ("second") per {
141        Second: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
142        Minute: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 60; f32|f64 = 60.;
143        Hour: [u16] u16|u32|u64|u128|usize|i16|i32|i64|i128|isize = 3_600; f32|f64 = 3_600.;
144        Day: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 86_400; f32|f64 = 86_400.;
145        Week: [u32] u32|u64|u128|usize|i32|i64|i128|isize = 604_800; f32|f64 = 604_800.;
146    }
147    Minute ("minute") per {
148        Minute: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
149        Hour: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 60; f32|f64 = 60.;
150        Day: [u16] u16|u32|u64|u128|usize|i16|i32|i64|i128|isize = 1_440; f32|f64 = 1_440.;
151        Week: [u16] u16|u32|u64|u128|usize|i16|i32|i64|i128|isize = 10_080; f32|f64 = 10_080.;
152    }
153    Hour ("hour") per {
154        Hour: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
155        Day: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 24; f32|f64 = 24.;
156        Week: [u8] u8|u16|u32|u64|u128|usize|i16|i32|i64|i128|isize = 168; f32|f64 = 168.;
157    }
158    Day ("day") per {
159        Day: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
160        Week: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 7; f32|f64 = 7.;
161    }
162    Week ("week") per {
163        Week: [u8] u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize = 1; f32|f64 = 1.;
164    }
165}