1use ::core::{fmt::Debug, time::Duration};
2
3#[inline]
5pub fn start() -> Sw<quanta::Instant> {
6 Sw {
7 elapsed: Duration::ZERO,
8 started: Some(quanta::Instant::now()),
9 }
10}
11
12pub trait Instant: Copy + Debug + Sized {
13 fn now() -> Self;
14 fn checked_add(&self, duration: Duration) -> Option<Self>;
15 fn checked_sub(&self, duration: Duration) -> Option<Self>;
16 fn saturating_duration_since(&self, earlier: Self) -> Duration;
17}
18
19impl Instant for quanta::Instant {
20 fn now() -> Self {
21 quanta::Instant::now()
22 }
23
24 fn checked_add(&self, duration: Duration) -> Option<Self> {
25 self.checked_add(duration)
26 }
27
28 fn checked_sub(&self, duration: Duration) -> Option<Self> {
29 self.checked_sub(duration)
30 }
31
32 fn saturating_duration_since(&self, earlier: Self) -> Duration {
33 self.saturating_duration_since(earlier)
34 }
35}
36
37#[derive(Clone, Copy, Debug)]
38pub struct Sw<I> {
39 elapsed: Duration,
40 started: Option<I>,
41}
42
43impl<I: Instant> Sw<I> {
44 #[inline]
49 pub fn new() -> Self {
50 Sw {
51 elapsed: Duration::ZERO,
52 started: None,
53 }
54 }
55
56 #[inline]
60 pub fn start(&mut self) {
61 self.started = Some(I::now())
62 }
63
64 #[inline]
68 pub fn stop(&mut self) {
69 self.elapsed += self
70 .started
71 .take()
72 .map(|earlier| I::now().saturating_duration_since(earlier))
73 .unwrap_or(Duration::ZERO);
74 }
75
76 #[inline]
78 pub fn finish(mut self) -> Duration {
79 self.stop();
80 self.elapsed
81 }
82}
83
84impl<I: Instant> Default for Sw<I> {
85 fn default() -> Self {
86 Sw::new()
87 }
88}