retry_policy/
retry_policy.rs1use core::{fmt, ops::ControlFlow, time::Duration};
2
3use retry_backoff::RetryBackoff;
4use retry_predicate::RetryPredicate;
5
6pub 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
35impl<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}