tryhard/
on_retry.rs

1use std::{
2    convert::Infallible,
3    future::{Future, Ready},
4    time::Duration,
5};
6
7/// Trait allowing you to run some future when a retry occurs. Could for example to be used for
8/// logging or other kinds of telemetry.
9///
10/// You wont have to implement this trait manually. It is implemented for functions with the right
11/// signature. See [`RetryFuture::on_retry`](struct.RetryFuture.html#method.on_retry) for more details.
12pub trait OnRetry<E> {
13    /// The type of the future you want to run.
14    type Future: Future<Output = ()> + Send + 'static;
15
16    /// Create another future to run.
17    ///
18    /// If `next_delay` is `None` then your future is out of retries and wont be called again.
19    fn on_retry(
20        &mut self,
21        attempt: u32,
22        next_delay: Option<Duration>,
23        previous_error: &E,
24    ) -> Self::Future;
25}
26
27/// A sentinel value that represents doing nothing in between retries.
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub struct NoOnRetry {
30    cannot_exist: Infallible,
31}
32
33impl<E> OnRetry<E> for NoOnRetry {
34    type Future = Ready<()>;
35
36    #[inline]
37    fn on_retry(&mut self, _: u32, _: Option<Duration>, _: &E) -> Self::Future {
38        match self.cannot_exist {}
39    }
40}
41
42impl<F, E, FutureT> OnRetry<E> for F
43where
44    F: Fn(u32, Option<Duration>, &E) -> FutureT,
45    FutureT: Future<Output = ()> + Send + 'static,
46    FutureT::Output: Send + 'static,
47{
48    type Future = FutureT;
49
50    #[inline]
51    fn on_retry(
52        &mut self,
53        attempts: u32,
54        next_delay: Option<Duration>,
55        previous_error: &E,
56    ) -> Self::Future {
57        self(attempts, next_delay, previous_error)
58    }
59}