waiter_trait/counter.rs
1use super::*;
2
3/// The timeout condition is independent of time
4/// and is determined solely by the number of times `timeout()` is called.
5///
6/// # Examples
7///
8/// ```
9/// use waiter_trait::{prelude::*, Counter};
10///
11/// let c = Counter::new(0);
12/// let mut t = c.start();
13/// assert!(t.timeout());
14/// assert!(t.timeout());
15///
16/// let c = Counter::new(usize::MAX);
17/// let mut t = c.start();
18/// assert!(!t.timeout());
19/// assert!(!t.timeout());
20///
21/// let c = Counter::new(2);
22/// let mut t = c.start();
23/// assert!(!t.timeout());
24/// assert!(!t.timeout());
25/// assert!(t.timeout());
26/// assert!(t.timeout());
27///
28/// t.restart();
29/// assert!(!t.timeout());
30/// assert!(!t.timeout());
31/// assert!(t.timeout());
32/// assert!(t.timeout());
33/// ```
34pub struct Counter {
35 retry_times: usize,
36}
37
38impl Counter {
39 /// - `retry_times`: The number of calls to `timeout()` before it returns `true`.
40 /// - If set to `0`, `timeout()` always returns `true`
41 /// - If set to `usize::MAX`, `timeout()` always returns `false`
42 pub fn new(retry_times: usize) -> Self {
43 Self { retry_times }
44 }
45}
46
47impl Waiter for Counter {
48 #[inline]
49 fn start(&self) -> impl WaiterStatus {
50 CounterInstance {
51 count: 0,
52 waiter: self,
53 }
54 }
55}
56
57pub struct CounterInstance<'a> {
58 count: usize,
59 waiter: &'a Counter,
60}
61
62impl<'a> WaiterStatus for CounterInstance<'a> {
63 #[inline]
64 fn timeout(&mut self) -> bool {
65 if self.waiter.retry_times == usize::MAX {
66 return false;
67 }
68
69 if self.count < self.waiter.retry_times {
70 self.count = self.count.wrapping_add(1);
71 false
72 } else {
73 true
74 }
75 }
76
77 #[inline(always)]
78 fn restart(&mut self) {
79 self.count = 0;
80 }
81}