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