backon/
sleep.rs

1use core::future::Future;
2use core::future::Ready;
3use core::time::Duration;
4
5/// A sleeper is used to generate a future that completes after a specified duration.
6pub trait Sleeper: 'static {
7    /// The future returned by the `sleep` method.
8    type Sleep: Future<Output = ()>;
9
10    /// Create a future that completes after a set period.
11    fn sleep(&self, dur: Duration) -> Self::Sleep;
12}
13
14/// A stub trait allowing non-[`Sleeper`] types to be used as a generic parameter in [`Retry`][crate::Retry].
15/// It does not provide actual functionality.
16#[doc(hidden)]
17pub trait MaybeSleeper: 'static {
18    type Sleep: Future<Output = ()>;
19}
20
21/// All `Sleeper` will implement  `MaybeSleeper`, but not vice versa.
22impl<T: Sleeper + ?Sized> MaybeSleeper for T {
23    type Sleep = <T as Sleeper>::Sleep;
24}
25
26/// All `Fn(Duration) -> impl Future<Output = ()>` implements `Sleeper`.
27impl<F: Fn(Duration) -> Fut + 'static, Fut: Future<Output = ()>> Sleeper for F {
28    type Sleep = Fut;
29
30    fn sleep(&self, dur: Duration) -> Self::Sleep {
31        self(dur)
32    }
33}
34
35/// The default implementation of `Sleeper` when no features are enabled.
36///
37/// It will fail to compile if a containing [`Retry`][crate::Retry] is `.await`ed without calling [`Retry::sleep`][crate::Retry::sleep] to provide a valid sleeper.
38#[cfg(all(not(feature = "tokio-sleep"), not(feature = "gloo-timers-sleep"),))]
39pub type DefaultSleeper = PleaseEnableAFeatureOrProvideACustomSleeper;
40/// The default implementation of `Sleeper` while feature `tokio-sleep` enabled.
41///
42/// it uses `tokio::time::sleep`.
43#[cfg(all(not(target_arch = "wasm32"), feature = "tokio-sleep"))]
44pub type DefaultSleeper = TokioSleeper;
45/// The default implementation of `Sleeper` while feature `gloo-timers-sleep` enabled.
46///
47/// It uses `gloo_timers::sleep::sleep`.
48#[cfg(all(target_arch = "wasm32", feature = "gloo-timers-sleep"))]
49pub type DefaultSleeper = GlooTimersSleep;
50
51/// A placeholder type that does not implement [`Sleeper`] and will therefore fail to compile if used as one.
52///
53/// Users should enable a feature of this crate that provides a valid [`Sleeper`] implementation when this type appears in compilation errors. Alternatively, a custom [`Sleeper`] implementation should be provided where necessary, such as in [`crate::Retry::sleeper`].
54#[doc(hidden)]
55#[derive(Clone, Copy, Debug, Default)]
56pub struct PleaseEnableAFeatureOrProvideACustomSleeper;
57
58/// Implement `MaybeSleeper` but not `Sleeper`.
59impl MaybeSleeper for PleaseEnableAFeatureOrProvideACustomSleeper {
60    type Sleep = Ready<()>;
61}
62
63/// The default implementation of `Sleeper` uses `tokio::time::sleep`.
64///
65/// It will adhere to [pausing/auto-advancing](https://docs.rs/tokio/latest/tokio/time/fn.pause.html)
66/// in Tokio's Runtime semantics, if enabled.
67#[cfg(all(not(target_arch = "wasm32"), feature = "tokio-sleep"))]
68#[derive(Clone, Copy, Debug, Default)]
69pub struct TokioSleeper;
70
71#[cfg(all(not(target_arch = "wasm32"), feature = "tokio-sleep"))]
72impl Sleeper for TokioSleeper {
73    type Sleep = tokio::time::Sleep;
74
75    fn sleep(&self, dur: Duration) -> Self::Sleep {
76        tokio::time::sleep(dur)
77    }
78}
79
80/// The implementation of `Sleeper` that uses `futures_timer::Delay`.
81///
82/// This implementation is based on
83/// the [`futures-timer`](https://docs.rs/futures-timer/latest/futures_timer/) crate.
84/// It is async runtime agnostic and will also work in WASM environments.
85#[cfg(feature = "futures-timer-sleep")]
86#[derive(Clone, Copy, Debug, Default)]
87pub struct FuturesTimerSleep;
88
89#[cfg(feature = "futures-timer-sleep")]
90impl Sleeper for FuturesTimerSleep {
91    type Sleep = futures_timer::Delay;
92
93    fn sleep(&self, dur: Duration) -> Self::Sleep {
94        futures_timer::Delay::new(dur)
95    }
96}
97
98/// The default implementation of `Sleeper` utilizes `gloo_timers::future::sleep`.
99#[cfg(all(target_arch = "wasm32", feature = "gloo-timers-sleep"))]
100#[derive(Clone, Copy, Debug, Default)]
101pub struct GlooTimersSleep;
102
103#[cfg(all(target_arch = "wasm32", feature = "gloo-timers-sleep"))]
104impl Sleeper for GlooTimersSleep {
105    type Sleep = gloo_timers::future::TimeoutFuture;
106
107    fn sleep(&self, dur: Duration) -> Self::Sleep {
108        gloo_timers::future::sleep(dur)
109    }
110}