relay_cogs/
measurement.rs

1use crate::time::{Duration, Instant};
2
3/// Simple collection of individual measurements.
4///
5/// Tracks the total time from starting the measurements as well as
6/// individual categorized measurements.
7pub struct Measurements {
8    start: Instant,
9    categorized: Vec<Measurement>,
10}
11
12impl Measurements {
13    /// Starts recording the first measurement.
14    pub fn start() -> Self {
15        Measurements {
16            start: Instant::now(),
17            categorized: Vec::new(),
18        }
19    }
20
21    /// Adds an individual categorized measurement.
22    pub fn add(&mut self, duration: Duration, category: &'static str) {
23        self.categorized.push(Measurement {
24            duration,
25            category: Some(category),
26        });
27    }
28
29    /// Finishes the current measurements and returns all individual
30    /// categorized measurements.
31    pub fn finish(&self) -> impl Iterator<Item = Measurement> + '_ {
32        let mut duration = self.start.elapsed();
33        for c in &self.categorized {
34            duration = duration.saturating_sub(c.duration);
35        }
36
37        std::iter::once(Measurement {
38            duration,
39            category: None,
40        })
41        .chain(self.categorized.iter().copied())
42        .filter(|m| !m.duration.is_zero())
43    }
44}
45
46/// A single, optionally, categorized measurement.
47#[derive(Copy, Clone)]
48pub struct Measurement {
49    /// Length of the measurement.
50    pub duration: Duration,
51    /// Optional category, if the measurement was categorized.
52    pub category: Option<&'static str>,
53}