4
4
// You may not use this file except in accordance with one or both of these
5
5
// licenses.
6
6
7
- //! [`Time`] trait and different implementations. Currently, it's mainly used in tests so we can
8
- //! manually advance time.
9
- //! Other crates may symlink this file to use it while [`Time`] trait is sealed here.
10
-
11
- use core:: ops:: Sub ;
12
- use core:: time:: Duration ;
13
-
14
- /// A measurement of time.
15
- pub trait Time : Copy + Sub < Duration , Output = Self > where Self : Sized {
16
- /// Returns an instance corresponding to the current moment.
17
- fn now ( ) -> Self ;
18
-
19
- /// Returns the amount of time passed between `earlier` and `self`.
20
- fn duration_since ( & self , earlier : Self ) -> Duration ;
21
- }
22
-
23
- /// A state in which time has no meaning.
24
- #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
25
- pub struct Eternity ;
26
-
27
- impl Time for Eternity {
28
- fn now ( ) -> Self {
29
- Self
30
- }
31
-
32
- fn duration_since ( & self , _earlier : Self ) -> Duration {
33
- Duration :: from_secs ( 0 )
34
- }
35
- }
36
-
37
- impl Sub < Duration > for Eternity {
38
- type Output = Self ;
39
-
40
- fn sub ( self , _other : Duration ) -> Self {
41
- self
42
- }
43
- }
44
-
45
- #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
46
- #[ cfg( feature = "std" ) ]
47
- pub struct MonotonicTime ( std:: time:: Instant ) ;
48
-
49
- /// The amount of time to shift `Instant` forward to prevent overflow when subtracting a `Duration`
50
- /// from `Instant::now` on some operating systems (e.g., iOS representing `Instance` as `u64`).
51
- #[ cfg( feature = "std" ) ]
52
- const SHIFT : Duration = Duration :: from_secs ( 10 * 365 * 24 * 60 * 60 ) ; // 10 years.
53
-
54
- #[ cfg( feature = "std" ) ]
55
- impl Time for MonotonicTime {
56
- fn now ( ) -> Self {
57
- let instant = std:: time:: Instant :: now ( ) . checked_add ( SHIFT ) . expect ( "Overflow on MonotonicTime instantiation" ) ;
58
- Self ( instant)
59
- }
60
-
61
- fn duration_since ( & self , earlier : Self ) -> Duration {
62
- // On rust prior to 1.60 `Instant::duration_since` will panic if time goes backwards.
63
- // However, we support rust versions prior to 1.60 and some users appear to have "monotonic
64
- // clocks" that go backwards in practice (likely relatively ancient kernels/etc). Thus, we
65
- // manually check for time going backwards here and return a duration of zero in that case.
66
- let now = Self :: now ( ) ;
67
- if now. 0 > earlier. 0 { now. 0 - earlier. 0 } else { Duration :: from_secs ( 0 ) }
68
- }
69
- }
70
-
71
- #[ cfg( feature = "std" ) ]
72
- impl Sub < Duration > for MonotonicTime {
73
- type Output = Self ;
74
-
75
- fn sub ( self , other : Duration ) -> Self {
76
- let instant = self . 0 . checked_sub ( other) . expect ( "MonotonicTime is not supposed to go backward futher than 10 years" ) ;
77
- Self ( instant)
78
- }
79
- }
7
+ //! A simple module which either re-exports [`std::time::Instant`] or a mocked version of it for
8
+ //! tests.
80
9
81
10
#[ cfg( test) ]
82
- pub mod tests {
83
- use super :: { Time , Eternity } ;
11
+ pub use test:: Instant ;
12
+ #[ cfg( not( test) ) ]
13
+ pub use std:: time:: Instant ;
84
14
15
+ #[ cfg( test) ]
16
+ mod test {
85
17
use core:: time:: Duration ;
86
18
use core:: ops:: Sub ;
87
19
use core:: cell:: Cell ;
88
20
89
21
/// Time that can be advanced manually in tests.
90
22
#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
91
- pub struct SinceEpoch ( Duration ) ;
23
+ pub struct Instant ( Duration ) ;
92
24
93
- impl SinceEpoch {
25
+ impl Instant {
94
26
thread_local ! {
95
27
static ELAPSED : Cell <Duration > = core:: cell:: Cell :: new( Duration :: from_secs( 0 ) ) ;
96
28
}
97
29
98
30
pub fn advance ( duration : Duration ) {
99
31
Self :: ELAPSED . with ( |elapsed| elapsed. set ( elapsed. get ( ) + duration) )
100
32
}
101
- }
102
33
103
- impl Time for SinceEpoch {
104
- fn now ( ) -> Self {
34
+ pub fn now ( ) -> Self {
105
35
Self ( Self :: ELAPSED . with ( |elapsed| elapsed. get ( ) ) )
106
36
}
107
37
108
- fn duration_since ( & self , earlier : Self ) -> Duration {
38
+ pub fn duration_since ( & self , earlier : Self ) -> Duration {
109
39
self . 0 - earlier. 0
110
40
}
111
41
}
112
42
113
- impl Sub < Duration > for SinceEpoch {
43
+ impl Sub < Duration > for Instant {
114
44
type Output = Self ;
115
45
116
46
fn sub ( self , other : Duration ) -> Self {
@@ -120,21 +50,13 @@ pub mod tests {
120
50
121
51
#[ test]
122
52
fn time_passes_when_advanced ( ) {
123
- let now = SinceEpoch :: now ( ) ;
53
+ let now = Instant :: now ( ) ;
124
54
125
- SinceEpoch :: advance ( Duration :: from_secs ( 1 ) ) ;
126
- SinceEpoch :: advance ( Duration :: from_secs ( 1 ) ) ;
55
+ Instant :: advance ( Duration :: from_secs ( 1 ) ) ;
56
+ Instant :: advance ( Duration :: from_secs ( 1 ) ) ;
127
57
128
- let later = SinceEpoch :: now ( ) ;
58
+ let later = Instant :: now ( ) ;
129
59
130
60
assert_eq ! ( now. 0 + Duration :: from_secs( 2 ) , later. 0 ) ;
131
61
}
132
-
133
- #[ test]
134
- fn time_never_passes_in_an_eternity ( ) {
135
- let now = Eternity :: now ( ) ;
136
- let later = Eternity :: now ( ) ;
137
-
138
- assert_eq ! ( later, now) ;
139
- }
140
62
}
0 commit comments