retry-policy 0.3.1

Retry Policy
Documentation
use core::{fmt, ops::ControlFlow, time::Duration};

use retry_backoff::RetryBackoff;
use retry_predicate::RetryPredicate;

//
pub trait RetryPolicy<PParams> {
    fn predicate(&self) -> &dyn RetryPredicate<PParams>;
    fn max_retries(&self) -> usize;
    fn backoff(&self) -> &dyn RetryBackoff;

    fn next_step(&self, params: &PParams, attempts: usize) -> ControlFlow<StopReason, Duration> {
        if attempts > self.max_retries() {
            return ControlFlow::Break(StopReason::MaxRetriesReached);
        }

        if !self.predicate().test(params) {
            return ControlFlow::Break(StopReason::PredicateFailed);
        }

        ControlFlow::Continue(self.backoff().delay(attempts))
    }

    fn name(&self) -> &str {
        "_"
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum StopReason {
    MaxRetriesReached,
    PredicateFailed,
}

//
impl<PParams> fmt::Debug for dyn RetryPolicy<PParams> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("RetryPolicy")
            .field(&RetryPolicy::name(self))
            .finish()
    }
}

impl<PParams> fmt::Debug for dyn RetryPolicy<PParams> + Send {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("RetryPolicy")
            .field(&RetryPolicy::name(self))
            .finish()
    }
}

impl<PParams> fmt::Debug for dyn RetryPolicy<PParams> + Send + Sync {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("RetryPolicy")
            .field(&RetryPolicy::name(self))
            .finish()
    }
}