ticky/
lib.rs

1/*
2	This file is part of Ticky.
3	Ticky is free software: you can redistribute it and/or modify
4	it under the terms of the GNU Affero General Public License as published by
5	the Free Software Foundation, either version 3 of the License, or
6	(at your option) any later version.
7	Ticky is distributed in the hope that it will be useful,
8	but WITHOUT ANY WARRANTY; without even the implied warranty of
9	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10	GNU Affero General Public License for more details.
11	You should have received a copy of the GNU Affero General Public License
12	along with Ticky.  If not, see <https://www.gnu.org/licenses/>.
13*/
14
15//! # Ticky
16//! A simple stopwatch implementation.
17//!
18//! ## Example
19//! ```rust
20//! use ticky::Stopwatch;
21//! let mut sw = Stopwatch::start_new();
22//! // Do something …
23//! sw.stop();
24//! println!("Elapsed time: {}ms", sw.elapsed_ms_whole());
25//! ```
26//!
27//! ## Features
28//! - `derive_more` - Enables using [`derive_more`](https://crates.io/crates/derive_more) for deriving `From`, `Into`, `Mul`, `MulAssign`, `Div`, `DivAssign`, `Rem`, `Shr`, and `Shl` for `Stopwatch`.
29//! - `hifitime` - Enables using [`hifitime`](https://crates.io/crates/hifitime) for high-resolution timekeeping.
30//! - `stdtime` - Enables using [`std::time`](https://doc.rust-lang.org/std/time/index.html) for timekeeping.
31//!
32//! Either `hifitime` or `stdtime` must be enabled. If neither is enabled, `stdtime` is used by default. If both are enabled, `hifitime` is used.
33//!
34//! ## Installation
35//! Run `cargo add ticky` to add Ticky to your `Cargo.toml` file.
36//!
37//! ## License
38//! Ticky is licensed under the [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html).
39//!
40//! ## Contributing
41//! Contributions are welcome! Please see [`CONTRIBUTING.md`](https://github.com/Dirout/ticky/blob/master/CONTRIBUTING.md) for more information.
42//!
43//! ## Authors
44//! - [Emil Sayahi](https://github.com/emmyoh)
45//!
46//! ## Acknowledgements
47//! - [`rust-stopwatch`](https://crates.io/crates/stopwatch) - The inspiration for this crate.
48
49#![no_std]
50#![warn(missing_docs)]
51
52#[cfg(feature = "std")]
53extern crate std;
54
55cfg_if::cfg_if! {
56	if #[cfg(any(feature = "hifitime"))] {
57		use hifitime::{Duration, Epoch, TimeUnits, Unit};
58
59		#[cfg(feature = "derive_more")]
60		use derive_more::{Div, DivAssign, From, Into, Mul, MulAssign, Rem, Shl, Shr};
61
62		#[cfg_attr(
63			feature = "derive_more",
64			derive(From, Into, Mul, MulAssign, Div, DivAssign, Rem, Shr, Shl,)
65		)]
66		#[derive(Ord, Eq, PartialEq, PartialOrd, Clone, Copy, Debug, Hash)]
67		/// A simple stopwatch implementation.
68		/// ## Usage
69		/// ```rust
70		/// use ticky::Stopwatch;
71		/// let mut sw = Stopwatch::start_new();
72		/// // Do something …
73		/// sw.stop();
74		/// println!("Elapsed time: {}ms", sw.elapsed_ms_whole());
75		/// ```
76		pub struct Stopwatch {
77			/// The total elapsed time.
78			pub elapsed: Duration,
79			/// The time at which the stopwatch was last started.
80			pub timer: Duration,
81			/// Whether the stopwatch is currently running.
82			pub is_running: bool,
83		}
84
85		impl Display for Stopwatch {
86			fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
87				write!(f, "{}", self.elapsed())
88			}
89		}
90
91		impl From<Duration> for Stopwatch {
92			fn from(dur: Duration) -> Self {
93				Self {
94					elapsed: dur,
95					timer: Epoch::now().unwrap().to_duration(),
96					is_running: false,
97				}
98			}
99		}
100
101		impl Default for Stopwatch {
102			fn default() -> Self {
103				Self {
104					elapsed: Duration::ZERO,
105					timer: Epoch::now().unwrap().to_duration(),
106					is_running: false,
107				}
108			}
109		}
110
111		impl Stopwatch {
112			/// Starts (or resumes) the stopwatch.
113			///
114			/// # Example
115			/// ```rust
116			/// use ticky::Stopwatch;
117			///
118			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
119			/// sw.start(); // Start the stopwatch
120			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
121			/// sw.stop(); // Stop the stopwatch (pausing it)
122			/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 100); // Allow for some error (± 100 milliseconds)
123			/// sw.start(); // Start the stopwatch again (resuming it)
124			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
125			/// sw.stop(); // Stop the stopwatch
126			/// assert!(sw.elapsed_ms_whole().abs_diff(2_000) < 100); // Allow for some error (± 100 milliseconds)
127			/// ```
128			pub fn start(&mut self) {
129				self.timer = Epoch::now().unwrap().to_duration();
130				self.is_running = true;
131			}
132
133			/// Stops (or pauses) the stopwatch.
134			///
135			/// # Example
136			/// ```rust
137			/// use ticky::Stopwatch;
138			///
139			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
140			/// sw.start(); // Start the stopwatch
141			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
142			/// sw.stop(); // Stop the stopwatch (pausing it)
143			/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 100); // Allow for some error (± 100 milliseconds)
144			/// sw.start(); // Start the stopwatch again (resuming it)
145			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
146			/// sw.stop(); // Stop the stopwatch
147			/// assert!(sw.elapsed_ms_whole().abs_diff(2_000) < 100); // Allow for some error (± 100 milliseconds)
148			/// ```
149			pub fn stop(&mut self) {
150				self.elapsed += (Epoch::now().unwrap().to_duration() - self.timer).abs();
151				self.is_running = false;
152			}
153
154			/// Returns the total elapsed time.
155			///
156			/// # Example
157			/// ```rust
158			/// use ticky::Stopwatch;
159			///
160			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
161			/// sw.start(); // Start the stopwatch
162			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
163			/// sw.stop(); // Stop the stopwatch
164			/// assert!((sw.elapsed().to_unit(hifitime::prelude::Unit::Millisecond) - 1_000.0).abs() < 100.0); // Allow for some error (± 100 milliseconds)
165			/// ```
166			pub fn elapsed(&self) -> Duration {
167				match self.is_running {
168					true =>  self.elapsed + (Epoch::now().unwrap().to_duration() - self.timer).abs(),
169					false => self.elapsed,
170				}
171			}
172
173			/// Returns the total elapsed time in fractional milliseconds.
174			///
175			/// # Example
176			/// ```rust
177			/// use ticky::Stopwatch;
178			///
179			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
180			/// sw.start(); // Start the stopwatch
181			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
182			/// sw.stop(); // Stop the stopwatch
183			/// assert!((sw.elapsed_ms() - 1_000.0).abs() < 100.0); // Allow for some error (± 100 milliseconds)
184			/// ```
185			pub fn elapsed_ms(&mut self) -> f64 {
186				self.elapsed().to_unit(Unit::Millisecond)
187			}
188
189			/// Returns the total elapsed time in whole milliseconds.
190			///
191			/// # Example
192			/// ```rust
193			/// use ticky::Stopwatch;
194			///
195			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
196			/// sw.start(); // Start the stopwatch
197			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
198			/// sw.stop(); // Stop the stopwatch
199			/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 100); // Allow for some error (± 100 milliseconds)
200			/// ```
201			pub fn elapsed_ms_whole(&mut self) -> u128 {
202				self.elapsed().round(1.milliseconds()).to_unit(Unit::Millisecond).round() as u128
203			}
204
205			/// Returns the total elapsed time in fractional microseconds.
206			///
207			/// # Example
208			/// ```rust
209			/// use ticky::Stopwatch;
210			///
211			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
212			/// sw.start(); // Start the stopwatch
213			/// std::thread::sleep(std::time::Duration::from_micros(1_000_000)); // Wait for 1 second
214			/// sw.stop(); // Stop the stopwatch
215			/// assert!((sw.elapsed_us() - 1_000_000.0).abs() < 10_000.0); // Allow for some error (± 10,000 microseconds)
216			/// ```
217			pub fn elapsed_us(&mut self) -> f64 {
218				self.elapsed().to_unit(Unit::Microsecond)
219			}
220
221			/// Returns the total elapsed time in whole microseconds.
222			///
223			/// # Example
224			/// ```rust
225			/// use ticky::Stopwatch;
226			///
227			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
228			/// sw.start(); // Start the stopwatch
229			/// std::thread::sleep(std::time::Duration::from_micros(1_000_000)); // Wait for 1 second
230			/// sw.stop(); // Stop the stopwatch
231			/// assert!(sw.elapsed_us_whole().abs_diff(1_000_000) < 10_000); // Allow for some error (± 10,000 microseconds)
232			/// ```
233			pub fn elapsed_us_whole(&mut self) -> u128 {
234				self.elapsed().round(1.microseconds()).to_unit(Unit::Microsecond).round() as u128
235			}
236
237			/// Returns the total elapsed time in fractional nanoseconds.
238			///
239			/// # Example
240			/// ```rust
241			/// use ticky::Stopwatch;
242			///
243			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
244			/// sw.start(); // Start the stopwatch
245			/// std::thread::sleep(std::time::Duration::from_nanos(1_000_000_000)); // Wait for 1 second
246			/// sw.stop(); // Stop the stopwatch
247			/// assert!((sw.elapsed_ns() - 1_000_000_000.0).abs() < 100_000_000.0); // Allow for some error (± 100,000,000 nanoseconds)
248			/// ```
249			pub fn elapsed_ns(&mut self) -> f64 {
250				self.elapsed().to_unit(Unit::Nanosecond)
251			}
252
253			/// Returns the total elapsed time in whole nanoseconds.
254			///
255			/// # Example
256			/// ```rust
257			/// use ticky::Stopwatch;
258			///
259			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
260			/// sw.start(); // Start the stopwatch
261			/// std::thread::sleep(std::time::Duration::from_nanos(1_000_000_000)); // Wait for 1 second
262			/// sw.stop(); // Stop the stopwatch
263			/// assert!(sw.elapsed_ns_whole().abs_diff(1_000_000_000) < 100_000_000); // Allow for some error (± 100,000,000 nanoseconds)
264			/// ```
265			pub fn elapsed_ns_whole(&mut self) -> u128 {
266				self.elapsed().total_nanoseconds().try_into().unwrap()
267			}
268
269			/// Returns the total elapsed time in fractional seconds.
270			///
271			/// # Example
272			/// ```rust
273			/// use ticky::Stopwatch;
274			///
275			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
276			/// sw.start(); // Start the stopwatch
277			/// std::thread::sleep(std::time::Duration::from_millis(1_500)); // Wait for 1.5 seconds
278			/// sw.stop(); // Stop the stopwatch
279			/// assert!((sw.elapsed_s() - 1.5).abs() < 0.01); // Allow for some error (± 0.01 seconds)
280			/// ```
281			pub fn elapsed_s(&mut self) -> f64 {
282				self.elapsed().to_unit(Unit::Second)
283			}
284
285			/// Returns the total elapsed time in whole seconds.
286			///
287			/// # Example
288			/// ```rust
289			/// use ticky::Stopwatch;
290			///
291			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
292			/// sw.start(); // Start the stopwatch
293			/// std::thread::sleep(std::time::Duration::from_millis(1_500)); // Wait for 1.5 seconds
294			/// sw.stop(); // Stop the stopwatch
295			/// assert_eq!(sw.elapsed_s_whole(), 2);
296			/// ```
297			pub fn elapsed_s_whole(&self) -> u64 {
298				self.elapsed().round(1.seconds()).to_seconds().round() as u64
299			}
300		}
301
302	} else if #[cfg(feature = "stdtime")] {
303		use core::time::Duration;
304
305		#[cfg(feature = "std")]
306		use std::time::Instant;
307
308		#[cfg(feature = "derive_more")]
309		use derive_more::{Div, DivAssign, From, Into, Mul, MulAssign, Rem, Shl, Shr};
310
311		#[cfg_attr(
312			feature = "derive_more",
313			derive(From, Into, Mul, MulAssign, Div, DivAssign, Rem, Shr, Shl,)
314		)]
315		#[derive(Ord, Eq, PartialEq, PartialOrd, Clone, Copy, Debug, Hash)]
316		/// A simple stopwatch implementation.
317		/// ## Usage
318		/// ```rust
319		/// use ticky::Stopwatch;
320		/// let mut sw = Stopwatch::start_new();
321		/// // Do something …
322		/// sw.stop();
323		/// println!("Elapsed time: {}ms", sw.elapsed_ms_whole());
324		/// ```
325		pub struct Stopwatch {
326			/// The total elapsed time.
327			pub elapsed: Duration,
328			/// The time at which the stopwatch was last started.
329			pub timer: Instant,
330			/// Whether the stopwatch is currently running.
331			pub is_running: bool,
332		}
333
334		impl Display for Stopwatch {
335			fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
336				let elapsed_ms = self.clone().elapsed_ms_whole();
337				write!(f, "{elapsed_ms}ms")
338			}
339		}
340
341		impl From<Duration> for Stopwatch {
342			fn from(dur: Duration) -> Self {
343				Self {
344					elapsed: dur,
345					timer: Instant::now(),
346					is_running: false,
347				}
348			}
349		}
350
351		impl Default for Stopwatch {
352			fn default() -> Self {
353				Self {
354					elapsed: Duration::new(0, 0),
355					timer: Instant::now(),
356					is_running: false,
357				}
358			}
359		}
360
361		impl Stopwatch {
362			/// Starts (or resumes) the stopwatch.
363			///
364			/// # Example
365			/// ```rust
366			/// use ticky::Stopwatch;
367			///
368			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
369			/// sw.start(); // Start the stopwatch
370			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
371			/// sw.stop(); // Stop the stopwatch (pausing it)
372			/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 100); // Allow for some error (± 100 milliseconds)
373			/// sw.start(); // Start the stopwatch again (resuming it)
374			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
375			/// sw.stop(); // Stop the stopwatch
376			/// assert!(sw.elapsed_ms_whole().abs_diff(2_000) < 100); // Allow for some error (± 100 milliseconds)
377			/// ```
378			pub fn start(&mut self) {
379				self.timer = Instant::now();
380				self.is_running = true;
381			}
382
383			/// Stops (or pauses) the stopwatch.
384			///
385			/// # Example
386			/// ```rust
387			/// use ticky::Stopwatch;
388			///
389			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
390			/// sw.start(); // Start the stopwatch
391			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
392			/// sw.stop(); // Stop the stopwatch (pausing it)
393			/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 100); // Allow for some error (± 100 milliseconds)
394			/// sw.start(); // Start the stopwatch again (resuming it)
395			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
396			/// sw.stop(); // Stop the stopwatch
397			/// assert!(sw.elapsed_ms_whole().abs_diff(2_000) < 100); // Allow for some error (± 100 milliseconds)
398			/// ```
399			pub fn stop(&mut self) {
400				self.elapsed += self.timer.elapsed();
401				self.is_running = false;
402			}
403
404			/// Returns the total elapsed time.
405			///
406			/// # Example
407			/// ```rust
408			/// use ticky::Stopwatch;
409			///
410			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
411			/// sw.start(); // Start the stopwatch
412			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
413			/// sw.stop(); // Stop the stopwatch
414			/// assert!(sw.elapsed().as_millis().abs_diff(1_000) < 100); // Allow for some error (± 100 milliseconds)
415			/// ```
416			pub fn elapsed(&self) -> Duration {
417				match self.is_running {
418					true => self.elapsed + self.timer.elapsed(),
419					false => self.elapsed,
420				}
421			}
422
423			/// Returns the total elapsed time in milliseconds.
424			///
425			/// # Example
426			/// ```rust
427			/// use ticky::Stopwatch;
428			///
429			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
430			/// sw.start(); // Start the stopwatch
431			/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
432			/// sw.stop(); // Stop the stopwatch
433			/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 100); // Allow for some error (± 100 milliseconds)
434			/// ```
435			pub fn elapsed_ms_whole(&mut self) -> u128 {
436				self.elapsed().as_millis()
437			}
438
439			/// Returns the total elapsed time in microseconds.
440			///
441			/// # Example
442			/// ```rust
443			/// use ticky::Stopwatch;
444			///
445			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
446			/// sw.start(); // Start the stopwatch
447			/// std::thread::sleep(std::time::Duration::from_micros(1_000_000)); // Wait for 1 second
448			/// sw.stop(); // Stop the stopwatch
449			/// assert!(sw.elapsed_us_whole().abs_diff(1_000_000) < 10_000); // Allow for some error (± 10,000 microseconds)
450			/// ```
451			pub fn elapsed_us_whole(&mut self) -> u128 {
452				self.elapsed().as_micros()
453			}
454
455			/// Returns the total elapsed time in nanoseconds.
456			///
457			/// # Example
458			/// ```rust
459			/// use ticky::Stopwatch;
460			///
461			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
462			/// sw.start(); // Start the stopwatch
463			/// std::thread::sleep(std::time::Duration::from_nanos(1_000_000_000)); // Wait for 1 second
464			/// sw.stop(); // Stop the stopwatch
465			/// assert!(sw.elapsed_ns_whole().abs_diff(1_000_000_000) < 100_000_000); // Allow for some error (± 100,000,000 nanoseconds)
466			/// ```
467			pub fn elapsed_ns_whole(&mut self) -> u128 {
468				self.elapsed().as_nanos()
469			}
470
471			/// Returns the total elapsed time in fractional seconds.
472			///
473			/// # Example
474			/// ```rust
475			/// use ticky::Stopwatch;
476			///
477			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
478			/// sw.start(); // Start the stopwatch
479			/// std::thread::sleep(std::time::Duration::from_millis(1_500)); // Wait for 1.5 seconds
480			/// sw.stop(); // Stop the stopwatch
481			/// assert!((sw.elapsed_s() - 1.5).abs() < 0.01); // Allow for some error (± 0.01 seconds)
482			/// ```
483			pub fn elapsed_s(&mut self) -> f64 {
484				self.elapsed().as_secs_f64()
485			}
486
487			/// Returns the total elapsed time in whole seconds.
488			///
489			/// # Example
490			/// ```rust
491			/// use ticky::Stopwatch;
492			///
493			/// let mut sw = Stopwatch::new(); // Create a new stopwatch
494			/// sw.start(); // Start the stopwatch
495			/// std::thread::sleep(std::time::Duration::from_millis(1_500)); // Wait for 1.5 seconds
496			/// sw.stop(); // Stop the stopwatch
497			/// assert_eq!(sw.elapsed_s_whole(), 1);
498			/// ```
499			pub fn elapsed_s_whole(&self) -> u64 {
500				self.elapsed().as_secs()
501			}
502		}
503	} else {
504		compile_error!("You must enable either the `stdtime` or `hifitime` feature.");
505	}
506}
507
508use core::fmt::{Display, Formatter};
509
510impl From<Stopwatch> for Duration {
511	fn from(sw: Stopwatch) -> Self {
512		sw.elapsed()
513	}
514}
515
516impl Stopwatch {
517	/// Creates a new stopwatch.
518	///
519	/// # Example
520	/// ```rust
521	/// use ticky::Stopwatch;
522	///
523	/// let mut sw = Stopwatch::new(); // Create a new stopwatch
524	/// sw.start(); // Start the stopwatch
525	/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
526	/// sw.stop(); // Stop the stopwatch
527	/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 10); // Allow for some error (± 10 milliseconds)
528	/// ```
529	pub fn new() -> Stopwatch {
530		Stopwatch::default()
531	}
532
533	/// Creates a new stopwatch and starts it.
534	///
535	/// # Example
536	/// ```rust
537	/// use ticky::Stopwatch;
538	///
539	/// let mut sw = Stopwatch::start_new(); // Create a new stopwatch, and start it
540	/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
541	/// sw.stop(); // Stop the stopwatch
542	/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 10); // Allow for some error (± 10 milliseconds)
543	/// ```
544	pub fn start_new() -> Stopwatch {
545		let mut sw = Stopwatch::new();
546		sw.start();
547		sw
548	}
549
550	/// Resets the stopwatch.
551	///
552	/// # Example
553	/// ```rust
554	/// use ticky::Stopwatch;
555	///
556	/// let mut sw = Stopwatch::new(); // Create a new stopwatch
557	/// sw.start(); // Start the stopwatch
558	/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
559	/// sw.stop(); // Stop the stopwatch
560	/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 10); // Allow for some error (± 10 milliseconds)
561	/// sw.reset(); // Reset the stopwatch
562	/// assert!(sw.elapsed_ms_whole().abs_diff(0) < 10); // Allow for some error (± 10 milliseconds)
563	/// sw.start(); // Start the stopwatch
564	/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
565	/// sw.stop(); // Stop the stopwatch
566	/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 10); // Allow for some error (± 10 milliseconds)
567	pub fn reset(&mut self) {
568		*self = Stopwatch::new();
569	}
570
571	/// Resets and starts the stopwatch.
572	///
573	/// # Example
574	/// ```rust
575	/// use ticky::Stopwatch;
576	///
577	/// let mut sw = Stopwatch::new(); // Create a new stopwatch
578	/// sw.start(); // Start the stopwatch
579	/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
580	/// sw.stop(); // Stop the stopwatch
581	/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 10); // Allow for some error (± 10 milliseconds)
582	/// sw.restart(); // Reset and start the stopwatch
583	/// std::thread::sleep(std::time::Duration::from_millis(1_000)); // Wait for 1 second
584	/// sw.stop(); // Stop the stopwatch
585	/// assert!(sw.elapsed_ms_whole().abs_diff(1_000) < 10); // Allow for some error (± 10 milliseconds)
586	pub fn restart(&mut self) {
587		self.reset();
588		self.start();
589	}
590
591	/// Returns true if the stopwatch is running, and false if not.
592	///
593	/// # Example
594	/// ```rust
595	/// use ticky::Stopwatch;
596	///
597	/// let mut sw = Stopwatch::new(); // Create a new stopwatch
598	/// assert_eq!(sw.is_running(), false); // The stopwatch is not running
599	/// sw.start(); // Start the stopwatch
600	/// assert_eq!(sw.is_running(), true); // The stopwatch is running
601	/// sw.stop(); // Stop the stopwatch
602	/// assert_eq!(sw.is_running(), false); // The stopwatch is not running
603	/// ```
604	pub fn is_running(&mut self) -> bool {
605		self.is_running
606	}
607}