Skip to main content

visual_cortex_capture/
rate.rs

1use std::time::Duration;
2
3/// How often a watcher evaluates, or a source captures. Stored as a period.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct Rate {
6    period: Duration,
7}
8
9impl Rate {
10    /// A rate of `hz` evaluations per second. Panics if `hz` is not positive and finite.
11    pub fn hz(hz: f64) -> Self {
12        assert!(
13            hz.is_finite() && hz > 0.0,
14            "Rate::hz requires a positive, finite value"
15        );
16        Self {
17            period: Duration::from_secs_f64(1.0 / hz),
18        }
19    }
20
21    /// One evaluation every `period`.
22    pub fn every(period: Duration) -> Self {
23        assert!(!period.is_zero(), "Rate::every requires a non-zero period");
24        Self { period }
25    }
26
27    pub fn period(&self) -> Duration {
28        self.period
29    }
30
31    pub fn is_faster_than(&self, other: &Rate) -> bool {
32        self.period < other.period
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn hz_converts_to_period() {
42        assert_eq!(Rate::hz(2.0).period(), Duration::from_millis(500));
43        assert_eq!(Rate::hz(10.0).period(), Duration::from_millis(100));
44    }
45
46    #[test]
47    fn every_wraps_a_duration() {
48        assert_eq!(
49            Rate::every(Duration::from_secs(3)).period(),
50            Duration::from_secs(3)
51        );
52    }
53
54    #[test]
55    fn faster_means_smaller_period() {
56        assert!(Rate::hz(10.0).is_faster_than(&Rate::hz(2.0)));
57        assert!(!Rate::hz(1.0).is_faster_than(&Rate::hz(1.0)));
58    }
59
60    #[test]
61    #[should_panic]
62    fn zero_hz_panics() {
63        let _ = Rate::hz(0.0);
64    }
65}