Skip to main content

futures_time/time/
duration.rs

1use crate::{
2    future::IntoFuture,
3    stream::{Interval, IntoStream},
4    task::Sleep,
5};
6
7use std::ops::{Add, AddAssign, Sub, SubAssign};
8
9use super::Instant;
10
11#[cfg(not(feature = "web"))]
12use std::time::Duration as HostDuration;
13
14#[cfg(feature = "web")]
15use web_time::Duration as HostDuration;
16
17/// A Duration type to represent a span of time, typically used for system
18/// timeouts.
19///
20/// This type wraps `std::time::Duration` so we can implement traits on it
21/// without coherence issues, just like if we were implementing this in the
22/// stdlib.
23#[derive(Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Clone, Copy)]
24pub struct Duration(pub(crate) HostDuration);
25impl Duration {
26    /// Creates a new `Duration` from the specified number of whole seconds and
27    /// additional nanoseconds.
28    #[must_use]
29    #[inline]
30    pub fn new(secs: u64, nanos: u32) -> Duration {
31        HostDuration::new(secs, nanos).into()
32    }
33
34    /// Creates a new `Duration` from the specified number of whole seconds.
35    #[must_use]
36    #[inline]
37    pub fn from_secs(secs: u64) -> Duration {
38        HostDuration::from_secs(secs).into()
39    }
40
41    /// Creates a new `Duration` from the specified number of milliseconds.
42    #[must_use]
43    #[inline]
44    pub fn from_millis(millis: u64) -> Self {
45        HostDuration::from_millis(millis).into()
46    }
47
48    /// Creates a new `Duration` from the specified number of microseconds.
49    #[must_use]
50    #[inline]
51    pub fn from_micros(micros: u64) -> Self {
52        HostDuration::from_micros(micros).into()
53    }
54
55    /// Creates a new `Duration` from the specified number of seconds represented
56    /// as `f64`.
57    ///
58    /// # Panics
59    /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
60    ///
61    /// # Examples
62    /// ```
63    /// use futures_time::time::Duration;
64    ///
65    /// let dur = Duration::from_secs_f64(2.7);
66    /// assert_eq!(dur, Duration::new(2, 700_000_000));
67    /// ```
68    #[must_use]
69    #[inline]
70    pub fn from_secs_f64(secs: f64) -> Duration {
71        HostDuration::from_secs_f64(secs).into()
72    }
73
74    /// Creates a new `Duration` from the specified number of seconds represented
75    /// as `f32`.
76    ///
77    /// # Panics
78    /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
79    #[must_use]
80    #[inline]
81    pub fn from_secs_f32(secs: f32) -> Duration {
82        HostDuration::from_secs_f32(secs).into()
83    }
84}
85
86impl std::ops::Deref for Duration {
87    type Target = HostDuration;
88
89    fn deref(&self) -> &Self::Target {
90        &self.0
91    }
92}
93
94impl std::ops::DerefMut for Duration {
95    fn deref_mut(&mut self) -> &mut Self::Target {
96        &mut self.0
97    }
98}
99
100impl From<HostDuration> for Duration {
101    fn from(inner: HostDuration) -> Self {
102        Self(inner)
103    }
104}
105
106impl Into<HostDuration> for Duration {
107    fn into(self) -> HostDuration {
108        self.0
109    }
110}
111
112impl Add<Duration> for Duration {
113    type Output = Self;
114
115    fn add(self, rhs: Duration) -> Self::Output {
116        (self.0 + rhs.0).into()
117    }
118}
119
120impl AddAssign<Duration> for Duration {
121    fn add_assign(&mut self, rhs: Duration) {
122        *self = (self.0 + rhs.0).into()
123    }
124}
125
126impl Sub<Duration> for Duration {
127    type Output = Self;
128
129    fn sub(self, rhs: Duration) -> Self::Output {
130        (self.0 - rhs.0).into()
131    }
132}
133
134impl SubAssign<Duration> for Duration {
135    fn sub_assign(&mut self, rhs: Duration) {
136        *self = (self.0 - rhs.0).into()
137    }
138}
139
140impl IntoFuture for Duration {
141    type Output = Instant;
142
143    type IntoFuture = Sleep;
144
145    fn into_future(self) -> Self::IntoFuture {
146        crate::task::sleep(self)
147    }
148}
149
150impl IntoStream for Duration {
151    type Item = Instant;
152
153    type IntoStream = Interval;
154
155    fn into_stream(self) -> Self::IntoStream {
156        crate::stream::interval(self)
157    }
158}