gglib_core/download/
throttle.rs1use std::time::{Duration, Instant};
12
13pub struct ProgressThrottle {
18 last_emit: Option<Instant>,
19 min_interval: Duration,
20}
21
22impl ProgressThrottle {
23 pub const fn new(min_interval: Duration) -> Self {
25 Self {
26 last_emit: None,
27 min_interval,
28 }
29 }
30
31 pub const fn default_interval() -> Self {
33 Self::new(Duration::from_millis(100))
34 }
35
36 pub fn should_emit(&mut self) -> bool {
38 let now = Instant::now();
39 match self.last_emit {
40 Some(last) if now.duration_since(last) < self.min_interval => false,
41 _ => {
42 self.last_emit = Some(now);
43 true
44 }
45 }
46 }
47
48 pub const fn reset(&mut self) {
50 self.last_emit = None;
51 }
52}
53
54impl Default for ProgressThrottle {
55 fn default() -> Self {
56 Self::default_interval()
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_throttle_first_emit() {
66 let mut throttle = ProgressThrottle::new(Duration::from_millis(100));
67 assert!(throttle.should_emit()); }
69
70 #[test]
71 fn test_throttle_respects_interval() {
72 let mut throttle = ProgressThrottle::new(Duration::from_millis(50));
73 assert!(throttle.should_emit());
74 assert!(!throttle.should_emit()); std::thread::sleep(Duration::from_millis(60));
77 assert!(throttle.should_emit()); }
79
80 #[test]
81 fn test_throttle_reset() {
82 let mut throttle = ProgressThrottle::new(Duration::from_millis(100));
83 throttle.should_emit();
84 assert!(!throttle.should_emit());
85
86 throttle.reset();
87 assert!(throttle.should_emit()); }
89}