benchmark_counters/
interval_checker.rs1use std::time::{Duration, Instant};
2
3pub struct IntervalChecker {
4 min: Duration,
5 max: Duration,
6 last_interval: Option<Instant>,
7 interval_counter: usize,
8 errors: usize,
9}
10
11impl IntervalChecker {
12 pub fn new(min: Duration, max: Duration) -> IntervalChecker {
13 IntervalChecker {
14 min,
15 max,
16 last_interval: None,
17 interval_counter: 0,
18 errors: 0,
19 }
20 }
21
22 pub fn tick<F>(&mut self, callback: F) -> bool
23 where
24 F: FnOnce(&IntervalChecker, &Duration),
25 {
26 let mut success = true;
27 if let Some(last_interval) = self.last_interval {
28 let elapsed = last_interval.elapsed();
29 if elapsed > self.max || elapsed < self.min {
30 self.errors += 1;
31 success = false;
32 callback(self, &elapsed);
33 }
34 }
35 self.last_interval = Some(Instant::now());
36 self.interval_counter += 1;
37 success
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44 use std::thread;
45
46 #[test]
47 fn test_interval() {
48 let mut c = IntervalChecker::new(Duration::from_millis(100), Duration::from_millis(1000));
49 c.tick(|_, _| panic!());
50 thread::sleep(Duration::from_millis(200));
51 c.tick(|_, _| panic!());
52 thread::sleep(Duration::from_millis(20));
53 let mut called = false;
54 c.tick(|checker, elapsed| {
55 called = true;
56 assert!(elapsed.as_millis() < 100 && elapsed.as_millis() >= 20);
57 assert_eq!(2, checker.interval_counter);
58 assert_eq!(1, checker.errors);
59 });
60 assert!(called);
61 }
62}