execution_time/
lib.rs

1mod time;
2mod traits;
3
4pub use self::{time::*, traits::*};
5use std::time::{Duration, Instant};
6
7/// Measures the execution time of a code block.
8///
9/// This struct provides methods to start a timer and print the elapsed time
10/// in a user-friendly format.
11pub struct ExecutionTime {
12    start_time: Instant,
13}
14
15impl ExecutionTime {
16    /// Starts a new stopwatch.
17    ///
18    /// This function initializes the timer by recording the current time.
19    ///
20    /// ### Examples
21    ///
22    /// ```
23    /// use execution_time::ExecutionTime;
24    ///
25    /// let timer = ExecutionTime::start();
26    /// // ... your code here ...
27    /// timer.print_elapsed_time();
28    /// ```
29    pub fn start() -> Self {
30        Self {
31            start_time: Instant::now(),
32        }
33    }
34
35    /// Gets the elapsed time as a `Duration`.
36    ///
37    /// `Duration` represents a span of time composed of whole seconds
38    /// and a fractional part represented in nanoseconds.
39    pub fn get_duration(&self) -> Duration {
40        self.start_time.elapsed()
41    }
42
43    /// Gets the elapsed time as a `Time` struct.
44    ///
45    /// This method converts the `Duration` into a `Time` struct, which
46    /// represents the time in terms of days, hours, minutes, and seconds.
47    pub fn get_time(&self) -> Time {
48        self.get_duration().get_time()
49    }
50
51    /// Calculates the time elapsed since the timer was started and formats it as a string.
52    ///
53    /// This method calculates the elapsed time, formats it into a readable string,
54    /// and includes both the formatted time and the raw `Duration` for debugging.
55    pub fn get_elapsed_time(&self) -> String {
56        let duration: Duration = self.get_duration();
57        let time: Time = duration.get_time();
58        format!("{} ({duration:?})", time.format_time())
59    }
60
61    /// Prints the time elapsed since the timer was started to the console.
62    ///
63    /// This method prints the formatted elapsed time to `stdout`.
64    pub fn print_elapsed_time(&self) {
65        println!("Elapsed time: {}", self.get_elapsed_time());
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    type Error = Box<dyn std::error::Error>;
73
74    #[test]
75    fn basic_timing() {
76        let timer = ExecutionTime::start();
77        std::thread::sleep(Duration::from_nanos(50));
78        let elapsed = timer.get_duration();
79        assert!(elapsed >= Duration::from_nanos(45)); // Allow some margin
80    }
81
82    #[test]
83    /// `cargo test -- --show-output main`
84    fn main() -> Result<(), Error> {
85        let timer = ExecutionTime::start();
86
87        let duration = timer.get_duration();
88        println!("duration: {duration:?}");
89
90        let time = duration.get_time();
91        println!("time: {time:?}");
92        println!("time: {time:#?}");
93
94        Ok(())
95    }
96
97    #[test]
98    /// `cargo test -- --show-output elapsed_time_more_than_nanosecond`
99    fn elapsed_time_more_than_nanosecond() -> Result<(), Error> {
100        let duration = Duration::new(0, 57); // 0_000_000_057
101        let time = duration.get_time();
102
103        let formatted_output = format!("{} ({duration:?})", time.format_time());
104
105        println!("duration: {duration:?}");
106        println!("time: {time:#?}");
107        println!("formatted_output: {formatted_output}\n");
108
109        assert_eq!(
110            time,
111            Time {
112                days: 0,
113                hours: 0,
114                minutes: 0,
115                seconds: 0.000000057,
116            }
117        );
118
119        assert_eq!(formatted_output, "0.000000057 second (57ns)");
120
121        Ok(())
122    }
123
124    #[test]
125    /// `cargo test -- --show-output elapsed_time_more_than_microsecond`
126    fn elapsed_time_more_than_microsecond() -> Result<(), Error> {
127        let duration = Duration::new(0, 80_057); // 0_000_080_057
128        let time = duration.get_time();
129
130        let formatted_output = format!("{} ({duration:?})", time.format_time());
131
132        println!("duration: {duration:?}");
133        println!("time: {time:#?}");
134        println!("formatted_output: {formatted_output}\n");
135
136        assert_eq!(
137            time,
138            Time {
139                days: 0,
140                hours: 0,
141                minutes: 0,
142                seconds: 0.000080057,
143            }
144        );
145
146        assert_eq!(formatted_output, "0.000080057 second (80.057µs)");
147
148        Ok(())
149    }
150
151    #[test]
152    /// `cargo test -- --show-output elapsed_time_more_than_millisecond`
153    fn elapsed_time_more_than_millisecond() -> Result<(), Error> {
154        let duration = Duration::new(0, 15_200_000); // 0_015_200_000
155        let time = duration.get_time();
156
157        let formatted_output = format!("{} ({duration:?})", time.format_time());
158
159        println!("duration: {duration:?}");
160        println!("time: {time:#?}");
161        println!("formatted_output: {formatted_output}\n");
162
163        assert_eq!(
164            time,
165            Time {
166                days: 0,
167                hours: 0,
168                minutes: 0,
169                seconds: 0.015200,
170            }
171        );
172
173        assert_eq!(formatted_output, "0.015200 second (15.2ms)");
174
175        Ok(())
176    }
177
178    #[test]
179    /// `cargo test -- --show-output elapsed_time_more_than_second`
180    fn elapsed_time_more_than_second() -> Result<(), Error> {
181        let duration = Duration::new(5, 80_012_045); // 5_080_012_045
182        let time = duration.get_time();
183
184        let formatted_output = format!("{} ({duration:?})", time.format_time());
185
186        println!("duration: {duration:?}");
187        println!("time: {time:#?}");
188        println!("formatted_output: {formatted_output}\n");
189
190        assert_eq!(
191            time,
192            Time {
193                days: 0,
194                hours: 0,
195                minutes: 0,
196                seconds: 5.080012045,
197            }
198        );
199
200        assert_eq!(formatted_output, "5.080 seconds (5.080012045s)");
201
202        Ok(())
203    }
204
205    #[test]
206    /// `cargo test -- --show-output elapsed_time_more_than_minute`
207    fn elapsed_time_more_than_minute() -> Result<(), Error> {
208        let duration = Duration::new(65, 12_345); // 65_000_012_345
209        let time = duration.get_time();
210
211        let formatted_output = format!("{} ({duration:?})", time.format_time());
212
213        println!("duration: {duration:?}");
214        println!("time: {time:#?}");
215        println!("formatted_output: {formatted_output}\n");
216
217        assert_eq!(
218            time,
219            Time {
220                days: 0,
221                hours: 0,
222                minutes: 1,
223                seconds: 5.000012345,
224            }
225        );
226
227        assert_eq!(formatted_output, "1 minute, 5.000 seconds (65.000012345s)");
228
229        Ok(())
230    }
231
232    #[test]
233    /// `cargo test -- --show-output elapsed_time_more_than_hour`
234    fn elapsed_time_more_than_hour() -> Result<(), Error> {
235        let duration = Duration::new(3700, 56_891_730); // 3700.056891730
236        let time = duration.get_time();
237
238        let formatted_output = format!("{} ({duration:?})", time.format_time());
239
240        println!("duration: {duration:?}");
241        println!("time: {time:#?}");
242        println!("formatted_output: {formatted_output}\n");
243
244        assert_eq!(
245            time,
246            Time {
247                days: 0,
248                hours: 1,
249                minutes: 1,
250                seconds: 40.05689173,
251            }
252        );
253
254        assert_eq!(
255            formatted_output,
256            "1 hour, 1 minute, 40.057 seconds (3700.05689173s)"
257        );
258
259        Ok(())
260    }
261
262    #[test]
263    /// `cargo test -- --show-output elapsed_time_more_than_day`
264    fn elapsed_time_more_than_day() -> Result<(), Error> {
265        let seconds = 86400.0 + 2.0 * 3600.0 + 5.0 * 60.0 + 28.03;
266        let duration = Duration::from_secs_f64(seconds); // 93928.0300
267        let time = duration.get_time();
268
269        let formatted_output = format!("{} ({duration:?})", time.format_time());
270
271        println!("duration: {duration:?}");
272        println!("time: {time:#?}");
273        println!("formatted_output: {formatted_output}\n");
274
275        assert_eq!(
276            time,
277            Time {
278                days: 1,
279                hours: 2,
280                minutes: 5,
281                seconds: 28.030000,
282            }
283        );
284
285        assert_eq!(
286            formatted_output,
287            "1 day, 2 hours, 5 minutes, 28.030 seconds (93928.03s)"
288        );
289
290        Ok(())
291    }
292}