1use std::{
3 future::Future,
4 pin::Pin,
5 task::{Context, Poll},
6 time::{Duration, Instant},
7};
8
9use pin_project_lite::pin_project;
10use wreq_proto::rt::{Executor, Sleep, Timer};
11
12#[non_exhaustive]
14#[derive(Default, Clone, Debug)]
15pub struct TokioExecutor {
16 _priv: (),
17}
18
19#[non_exhaustive]
21#[derive(Default, Clone, Debug)]
22pub struct TokioTimer {
23 _priv: (),
24}
25
26pin_project! {
29 #[derive(Debug)]
30 struct TokioSleep {
31 #[pin]
32 inner: tokio::time::Sleep,
33 }
34}
35
36impl<Fut> Executor<Fut> for TokioExecutor
39where
40 Fut: Future + Send + 'static,
41 Fut::Output: Send + 'static,
42{
43 #[inline]
44 fn execute(&self, fut: Fut) {
45 tokio::spawn(fut);
46 }
47}
48
49impl TokioExecutor {
50 #[inline]
52 pub fn new() -> Self {
53 Self { _priv: () }
54 }
55}
56
57impl Timer for TokioTimer {
60 #[inline]
61 fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
62 Box::pin(TokioSleep {
63 inner: tokio::time::sleep(duration),
64 })
65 }
66
67 #[inline]
68 fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
69 Box::pin(TokioSleep {
70 inner: tokio::time::sleep_until(deadline.into()),
71 })
72 }
73
74 #[inline]
75 fn now(&self) -> Instant {
76 tokio::time::Instant::now().into()
77 }
78
79 #[inline]
80 fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
81 sleep.as_mut().reset(new_deadline);
82 }
83}
84
85impl TokioTimer {
86 #[inline]
88 pub fn new() -> Self {
89 Self { _priv: () }
90 }
91}
92
93impl Future for TokioSleep {
96 type Output = ();
97
98 #[inline]
99 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
100 self.project().inner.poll(cx)
101 }
102}
103
104impl Sleep for TokioSleep {
105 #[inline]
106 fn reset(self: Pin<&mut Self>, deadline: Instant) {
107 self.project().inner.as_mut().reset(deadline.into());
108 }
109}