use super::super::execution::common::RetryOp;
use super::super::execution::sync_exec::{NoSyncSleep, SyncRetryExec, SyncRetryExecWithStats};
use super::super::time::ElapsedTracker;
use super::super::{ExecutionHooks, RetryPolicy};
use crate::state::RetryState;
use crate::{predicate, stop, wait};
pub trait RetryExt<T, E>: FnMut() -> Result<T, E> + Sized {
fn retry(self) -> DefaultSyncRetryBuilder<Self, T, E>;
}
#[doc(hidden)]
pub struct StatelessOp<F>(F);
impl<T, E, F: FnMut() -> Result<T, E>> RetryOp<T, E> for StatelessOp<F> {
fn call_op(&mut self, _state: RetryState) -> Result<T, E> {
(self.0)()
}
}
impl<T, E, F> RetryExt<T, E> for F
where
F: FnMut() -> Result<T, E> + Sized,
{
fn retry(self) -> DefaultSyncRetryBuilder<Self, T, E> {
SyncRetryExec::new(
RetryPolicy::default(),
ExecutionHooks::new(),
StatelessOp(self),
NoSyncSleep,
ElapsedTracker::new(None),
)
}
}
pub type SyncRetryBuilder<S, W, P, BA, AA, OX, F, SleepFn, T, E> =
SyncRetryExec<RetryPolicy<S, W, P>, BA, AA, OX, F, SleepFn, T, E>;
pub type SyncRetryBuilderWithStats<S, W, P, BA, AA, OX, F, SleepFn, T, E> =
SyncRetryExecWithStats<RetryPolicy<S, W, P>, BA, AA, OX, F, SleepFn, T, E>;
pub type DefaultSyncRetryBuilder<F, T, E> = SyncRetryBuilder<
stop::StopAfterAttempts,
wait::WaitExponential,
predicate::PredicateAnyError,
(),
(),
(),
StatelessOp<F>,
NoSyncSleep,
T,
E,
>;
pub type DefaultSyncRetryBuilderWithStats<F, SleepFn, T, E> = SyncRetryBuilderWithStats<
stop::StopAfterAttempts,
wait::WaitExponential,
predicate::PredicateAnyError,
(),
(),
(),
StatelessOp<F>,
SleepFn,
T,
E,
>;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[allow(dead_code)]
fn _sync_retry_builder_requires_sleep_in_no_std() {}
impl<S, W, P, F, T, E> SyncRetryExec<RetryPolicy<S, W, P>, (), (), (), F, NoSyncSleep, T, E> {
pub(crate) fn from_policy(policy: RetryPolicy<S, W, P>, op: F) -> Self {
SyncRetryExec::new(
policy,
ExecutionHooks::new(),
op,
NoSyncSleep,
ElapsedTracker::new(None),
)
}
}
#[allow(clippy::type_complexity)]
impl<S, W, P, BA, AA, OX, F, SleepFn, T, E>
SyncRetryExec<RetryPolicy<S, W, P>, BA, AA, OX, F, SleepFn, T, E>
{
#[must_use]
pub fn stop<NewStop>(
self,
stop: NewStop,
) -> SyncRetryExec<RetryPolicy<NewStop, W, P>, BA, AA, OX, F, SleepFn, T, E> {
self.map_policy(|policy| policy.stop(stop))
}
#[must_use]
pub fn wait<NewWait>(
self,
wait: NewWait,
) -> SyncRetryExec<RetryPolicy<S, NewWait, P>, BA, AA, OX, F, SleepFn, T, E> {
self.map_policy(|policy| policy.wait(wait))
}
#[must_use]
pub fn when<NewPredicate>(
self,
predicate: NewPredicate,
) -> SyncRetryExec<RetryPolicy<S, W, NewPredicate>, BA, AA, OX, F, SleepFn, T, E> {
self.map_policy(|policy| policy.when(predicate))
}
#[must_use]
pub fn until<NewPredicate>(
self,
predicate: NewPredicate,
) -> SyncRetryExec<
RetryPolicy<S, W, predicate::PredicateUntil<NewPredicate>>,
BA,
AA,
OX,
F,
SleepFn,
T,
E,
> {
self.map_policy(|policy| policy.until(predicate))
}
}