backon/backoff/
api.rs

1use core::time::Duration;
2
3/// Backoff is an [`Iterator`] that returns [`Duration`].
4///
5/// - `Some(Duration)` indicates the caller should `sleep(Duration)` and retry the request.
6/// - `None` indicates the limits have been reached, and the caller should return the current error instead.
7pub trait Backoff: Iterator<Item = Duration> + Send + Sync + Unpin {}
8impl<T> Backoff for T where T: Iterator<Item = Duration> + Send + Sync + Unpin {}
9
10/// BackoffBuilder is utilized to construct a new backoff.
11pub trait BackoffBuilder: Send + Sync + Unpin {
12    /// The associated backoff returned by this builder.
13    type Backoff: Backoff;
14
15    /// Construct a new backoff using the builder.
16    fn build(self) -> Self::Backoff;
17}
18
19impl<B: Backoff> BackoffBuilder for B {
20    type Backoff = B;
21
22    fn build(self) -> Self::Backoff {
23        self
24    }
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30    use crate::ConstantBuilder;
31    use crate::ExponentialBuilder;
32    use crate::FibonacciBuilder;
33
34    fn test_fn_builder(b: impl BackoffBuilder) {
35        let _ = b.build();
36    }
37
38    #[test]
39    fn test_backoff_builder() {
40        test_fn_builder([Duration::from_secs(1)].into_iter());
41
42        // Just for test if user can keep using &XxxBuilder.
43        #[allow(clippy::needless_borrows_for_generic_args)]
44        {
45            test_fn_builder(&ConstantBuilder::default());
46            test_fn_builder(&FibonacciBuilder::default());
47            test_fn_builder(&ExponentialBuilder::default());
48        }
49    }
50}