retry_policy/
retry_policy.rs

1use core::{fmt, ops::ControlFlow, time::Duration};
2
3use retry_backoff::RetryBackoff;
4use retry_predicate::RetryPredicate;
5
6//
7pub trait RetryPolicy<PParams> {
8    fn predicate(&self) -> &dyn RetryPredicate<PParams>;
9    fn max_retries(&self) -> usize;
10    fn backoff(&self) -> &dyn RetryBackoff;
11
12    fn next_step(&self, params: &PParams, attempts: usize) -> ControlFlow<StopReason, Duration> {
13        if attempts > self.max_retries() {
14            return ControlFlow::Break(StopReason::MaxRetriesReached);
15        }
16
17        if !self.predicate().test(params) {
18            return ControlFlow::Break(StopReason::PredicateFailed);
19        }
20
21        ControlFlow::Continue(self.backoff().delay(attempts))
22    }
23
24    fn name(&self) -> &str {
25        "_"
26    }
27}
28
29#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
30pub enum StopReason {
31    MaxRetriesReached,
32    PredicateFailed,
33}
34
35//
36impl<PParams> fmt::Debug for dyn RetryPolicy<PParams> {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        f.debug_tuple("RetryPolicy")
39            .field(&RetryPolicy::name(self))
40            .finish()
41    }
42}
43
44impl<PParams> fmt::Debug for dyn RetryPolicy<PParams> + Send {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        f.debug_tuple("RetryPolicy")
47            .field(&RetryPolicy::name(self))
48            .finish()
49    }
50}
51
52impl<PParams> fmt::Debug for dyn RetryPolicy<PParams> + Send + Sync {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        f.debug_tuple("RetryPolicy")
55            .field(&RetryPolicy::name(self))
56            .finish()
57    }
58}