Skip to main content

time/ext/
numerical_duration.rs

1use crate::SignedDuration;
2use crate::unit::*;
3
4/// Sealed trait to prevent downstream implementations.
5mod sealed {
6    /// A trait that cannot be implemented by downstream users.
7    pub trait Sealed {}
8    impl Sealed for i64 {}
9    impl Sealed for f64 {}
10}
11
12/// Create [`SignedDuration`]s from numeric literals.
13///
14/// # Examples
15///
16/// Basic construction of [`SignedDuration`]s.
17///
18/// ```rust
19/// # use time::{SignedDuration, ext::NumericalDuration};
20/// assert_eq!(5.nanoseconds(), SignedDuration::nanoseconds(5));
21/// assert_eq!(5.microseconds(), SignedDuration::microseconds(5));
22/// assert_eq!(5.milliseconds(), SignedDuration::milliseconds(5));
23/// assert_eq!(5.seconds(), SignedDuration::seconds(5));
24/// assert_eq!(5.minutes(), SignedDuration::minutes(5));
25/// assert_eq!(5.hours(), SignedDuration::hours(5));
26/// assert_eq!(5.days(), SignedDuration::days(5));
27/// assert_eq!(5.weeks(), SignedDuration::weeks(5));
28/// ```
29///
30/// Signed integers work as well!
31///
32/// ```rust
33/// # use time::{SignedDuration, ext::NumericalDuration};
34/// assert_eq!((-5).nanoseconds(), SignedDuration::nanoseconds(-5));
35/// assert_eq!((-5).microseconds(), SignedDuration::microseconds(-5));
36/// assert_eq!((-5).milliseconds(), SignedDuration::milliseconds(-5));
37/// assert_eq!((-5).seconds(), SignedDuration::seconds(-5));
38/// assert_eq!((-5).minutes(), SignedDuration::minutes(-5));
39/// assert_eq!((-5).hours(), SignedDuration::hours(-5));
40/// assert_eq!((-5).days(), SignedDuration::days(-5));
41/// assert_eq!((-5).weeks(), SignedDuration::weeks(-5));
42/// ```
43///
44/// Just like any other [`SignedDuration`], they can be added, subtracted, etc.
45///
46/// ```rust
47/// # use time::ext::NumericalDuration;
48/// assert_eq!(2.seconds() + 500.milliseconds(), 2_500.milliseconds());
49/// assert_eq!(2.seconds() - 500.milliseconds(), 1_500.milliseconds());
50/// ```
51///
52/// When called on floating point values, any remainder of the floating point value will be
53/// truncated. Keep in mind that floating point numbers are inherently imprecise and have
54/// limited capacity.
55#[diagnostic::on_unimplemented(note = "this extension trait is intended to be used with numeric \
56                                       literals, such as `5.seconds()`")]
57pub trait NumericalDuration: sealed::Sealed {
58    /// Create a [`SignedDuration`] from the number of nanoseconds.
59    fn nanoseconds(self) -> SignedDuration;
60    /// Create a [`SignedDuration`] from the number of microseconds.
61    fn microseconds(self) -> SignedDuration;
62    /// Create a [`SignedDuration`] from the number of milliseconds.
63    fn milliseconds(self) -> SignedDuration;
64    /// Create a [`SignedDuration`] from the number of seconds.
65    fn seconds(self) -> SignedDuration;
66    /// Create a [`SignedDuration`] from the number of minutes.
67    fn minutes(self) -> SignedDuration;
68    /// Create a [`SignedDuration`] from the number of hours.
69    fn hours(self) -> SignedDuration;
70    /// Create a [`SignedDuration`] from the number of days.
71    fn days(self) -> SignedDuration;
72    /// Create a [`SignedDuration`] from the number of weeks.
73    fn weeks(self) -> SignedDuration;
74}
75
76impl NumericalDuration for i64 {
77    #[inline]
78    fn nanoseconds(self) -> SignedDuration {
79        SignedDuration::nanoseconds(self)
80    }
81
82    #[inline]
83    fn microseconds(self) -> SignedDuration {
84        SignedDuration::microseconds(self)
85    }
86
87    #[inline]
88    fn milliseconds(self) -> SignedDuration {
89        SignedDuration::milliseconds(self)
90    }
91
92    #[inline]
93    fn seconds(self) -> SignedDuration {
94        SignedDuration::seconds(self)
95    }
96
97    #[inline]
98    #[track_caller]
99    fn minutes(self) -> SignedDuration {
100        SignedDuration::minutes(self)
101    }
102
103    #[inline]
104    #[track_caller]
105    fn hours(self) -> SignedDuration {
106        SignedDuration::hours(self)
107    }
108
109    #[inline]
110    #[track_caller]
111    fn days(self) -> SignedDuration {
112        SignedDuration::days(self)
113    }
114
115    #[inline]
116    #[track_caller]
117    fn weeks(self) -> SignedDuration {
118        SignedDuration::weeks(self)
119    }
120}
121
122impl NumericalDuration for f64 {
123    #[inline]
124    fn nanoseconds(self) -> SignedDuration {
125        SignedDuration::nanoseconds(self as i64)
126    }
127
128    #[inline]
129    fn microseconds(self) -> SignedDuration {
130        SignedDuration::nanoseconds((self * Nanosecond::per_t::<Self>(Microsecond)) as i64)
131    }
132
133    #[inline]
134    fn milliseconds(self) -> SignedDuration {
135        SignedDuration::nanoseconds((self * Nanosecond::per_t::<Self>(Millisecond)) as i64)
136    }
137
138    #[inline]
139    fn seconds(self) -> SignedDuration {
140        SignedDuration::nanoseconds((self * Nanosecond::per_t::<Self>(Second)) as i64)
141    }
142
143    #[inline]
144    #[track_caller]
145    fn minutes(self) -> SignedDuration {
146        SignedDuration::nanoseconds((self * Nanosecond::per_t::<Self>(Minute)) as i64)
147    }
148
149    #[inline]
150    #[track_caller]
151    fn hours(self) -> SignedDuration {
152        SignedDuration::nanoseconds((self * Nanosecond::per_t::<Self>(Hour)) as i64)
153    }
154
155    #[inline]
156    #[track_caller]
157    fn days(self) -> SignedDuration {
158        SignedDuration::nanoseconds((self * Nanosecond::per_t::<Self>(Day)) as i64)
159    }
160
161    #[inline]
162    #[track_caller]
163    fn weeks(self) -> SignedDuration {
164        SignedDuration::nanoseconds((self * Nanosecond::per_t::<Self>(Week)) as i64)
165    }
166}