cyper_core/
executor.rs

1use std::{
2    future::Future,
3    pin::Pin,
4    task::{Context, Poll},
5    time::{Duration, Instant},
6};
7
8use hyper::rt::{Executor, Sleep, Timer};
9use send_wrapper::SendWrapper;
10
11/// An executor service based on [`compio::runtime`]. It uses
12/// [`compio::runtime::spawn`] interally.
13#[derive(Debug, Default, Clone)]
14pub struct CompioExecutor;
15
16impl<F: Future<Output = ()> + Send + 'static> Executor<F> for CompioExecutor {
17    fn execute(&self, fut: F) {
18        compio::runtime::spawn(fut).detach();
19    }
20}
21
22struct SleepFuture<T: Send + Sync + Future<Output = ()>>(T);
23
24impl<T: Send + Sync + Future<Output = ()>> Sleep for SleepFuture<T> {}
25
26impl<T: Send + Sync + Future<Output = ()>> Future for SleepFuture<T> {
27    type Output = ();
28
29    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
30        unsafe { self.map_unchecked_mut(|this| &mut this.0) }.poll(cx)
31    }
32}
33
34/// An timer service based on [`compio::time`].
35#[derive(Debug, Default, Clone)]
36pub struct CompioTimer;
37
38impl Timer for CompioTimer {
39    fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
40        Box::pin(SleepFuture(SendWrapper::new(compio::time::sleep(duration))))
41    }
42
43    fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
44        Box::pin(SleepFuture(SendWrapper::new(compio::time::sleep_until(
45            deadline,
46        ))))
47    }
48}