1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//! Time source abstraction for rate limiting operations.
//!
//! This module provides the TimeSource trait which abstracts different time
//! sources while maintaining a clean separation of concerns. TimeSource is
//! responsible for providing elapsed Duration since some starting point,
//! while Precision handles the conversion to tick values.
//!
//! # Design Philosophy
//!
//! The TimeSource abstraction enables:
//! - **Testability**: MockTimeSource for deterministic testing
//! - **Flexibility**: Support for different time sources (std::time, tokio, etc.)
//! - **Isolation**: Clean separation between time acquisition and precision conversion
//! - **Performance**: Zero-cost abstractions through static dispatch
//!
//! # Time Model
//!
//! TimeSource implementations follow an "elapsed time" model similar to
//! `std::time::Instant::elapsed()`. Each TimeSource has an implicit starting
//! point and returns the Duration elapsed since that point.
//!
//! This model ensures:
//! - Monotonic time progression
//! - Consistent behavior across different sources
//! - Natural integration with Duration-based APIs
//!
//! # Examples
//!
//! ## Basic Usage
//!
//! ```rust
//! use rate_guard::time_source::{TimeSource, MockTimeSource};
//! use std::time::Duration;
//!
//! let time_source = MockTimeSource::new();
//! let elapsed = time_source.now();
//! assert_eq!(elapsed, Duration::ZERO);
//!
//! time_source.advance(Duration::from_millis(100));
//! let elapsed = time_source.now();
//! assert_eq!(elapsed, Duration::from_millis(100));
//! ```
//!
//! ## Integration with Precision
//!
//! ```rust
//! use rate_guard::time_source::{TimeSource, MockTimeSource};
//! use rate_guard::precision::{Precision, Millis};
//! use std::time::Duration;
//!
//! let time_source = MockTimeSource::new();
//! time_source.advance(Duration::from_millis(250));
//!
//! let elapsed = time_source.now();
//! let ticks = Millis::to_ticks(elapsed);
//! assert_eq!(ticks, 250);
//! ```
use Duration;
pub use MockTimeSource;
pub use StdTimeSource;
pub use TokioTimeSource;
/// Trait for providing elapsed time since a starting point.
///
/// TimeSource implementations abstract different sources of time while
/// maintaining consistent "elapsed time" semantics. Each implementation
/// has an implicit starting point and returns the Duration elapsed since
/// that point.
///
/// # Contract
///
/// Implementations must guarantee:
/// - **Monotonicity**: `now()` never decreases between calls
/// - **Zero start**: The first call to `now()` should return `Duration::ZERO`
/// or close to it
/// - **Consistency**: Multiple calls without time progression return the same value
/// - **Reasonable precision**: Should provide precision appropriate for the use case
///
/// # Performance Requirements
///
/// - Methods should be marked `#[inline(always)]` when possible
/// - Implementations should minimize allocation and system calls
/// - The abstraction should compile to efficient machine code
///
/// # Examples
///
/// ## Implementing a Custom TimeSource
///
/// ```rust
/// use rate_guard::time_source::TimeSource;
/// use std::time::{Duration, Instant};
///
/// struct CustomTimeSource {
/// start: Instant,
/// }
///
/// impl CustomTimeSource {
/// fn new() -> Self {
/// Self {
/// start: Instant::now(),
/// }
/// }
/// }
///
/// impl TimeSource for CustomTimeSource {
/// fn now(&self) -> Duration {
/// self.start.elapsed()
/// }
/// }
/// ```
///
/// ## Usage in Rate Limiting
///
/// ```rust
/// use rate_guard::time_source::{TimeSource, MockTimeSource};
/// use rate_guard::precision::{Precision, Millis};
/// use rate_guard::types::Uint;
/// use std::time::Duration;
///
/// fn get_current_ticks<T: TimeSource, P: Precision>(time_source: &T) -> Uint {
/// let elapsed = time_source.now();
/// P::to_ticks(elapsed)
/// }
///
/// let time_source = MockTimeSource::new();
/// time_source.advance(Duration::from_millis(500));
///
/// let ticks = get_current_ticks::<_, Millis>(&time_source);
/// assert_eq!(ticks, 500);
/// ```