1use std::{future::IntoFuture, time::Duration};
2
3use tokio::time::{error::Elapsed, timeout, Timeout};
4
5pub type Result<T> = std::result::Result<T, Elapsed>;
6
7#[derive(Debug)]
8pub enum RetryState<T> {
9 Ok(T),
10 Retry,
11 TimedOut,
12}
13
14#[derive(Debug, Default)]
15pub struct Retry {
16 pub attempts: u8,
17}
18
19impl Retry {
20 pub fn reset(&mut self) {
21 self.attempts = 0;
22 }
23
24 pub fn timeout<F: IntoFuture>(&self, f: F) -> Timeout<F::IntoFuture> {
25 timeout(Duration::from_secs(30), f)
26 }
27
28 pub fn next<T>(&mut self, res: Result<T>) -> RetryState<T> {
29 match res.ok() {
30 Some(res) => {
31 return RetryState::Ok(res);
32 }
33 None if self.attempts < 3 => {
34 self.attempts += 1;
35 return RetryState::Retry;
36 }
37 None => {
38 return RetryState::TimedOut;
39 }
40 }
41 }
42}