use std::{
future::Future,
pin::Pin,
sync::Arc,
time::{Duration, Instant},
};
use wreq_proto::rt::{self, Sleep, Time};
pub type BoxSendFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
#[derive(Clone)]
pub struct Executor(Arc<dyn rt::Executor<BoxSendFuture> + Send + Sync>);
impl Executor {
#[inline]
pub fn new<E>(exec: E) -> Self
where
E: rt::Executor<BoxSendFuture> + Send + Sync + 'static,
{
Executor(Arc::new(exec))
}
}
impl<Fut> rt::Executor<Fut> for Executor
where
Fut: Future<Output = ()> + Send + 'static,
{
#[track_caller]
#[inline(always)]
fn execute(&self, fut: Fut) {
self.0.execute(Box::pin(fut))
}
}
impl Default for Executor {
#[inline]
fn default() -> Self {
if_tokio_rt!(block: {
return Executor(Arc::new(wreq_rt::rt::tokio::TokioExecutor::new()))
});
if_compio_rt!(block: {
return Executor(Arc::new(wreq_rt::rt::compio::CompioExecutor::new()))
});
if_all_rt!(block: {
return Executor(Arc::new(wreq_rt::rt::tokio::TokioExecutor::new()))
});
if_no_rt!(block:{
panic!(
"no async runtime feature enabled; at least one of `tokio-rt` or `compio-rt` must be active"
);
});
}
}
#[derive(Clone)]
pub struct Timer(Time);
impl Timer {
#[inline]
pub fn new<M>(timer: M) -> Self
where
M: rt::Timer + Send + Sync + 'static,
{
Timer(Time::Timer(Arc::new(timer)))
}
#[cfg(test)]
#[doc(hidden)]
pub fn empty() -> Self {
Timer(Time::Empty)
}
#[inline]
pub fn is_empty(&self) -> bool {
matches!(self.0, Time::Empty)
}
}
impl Default for Timer {
#[inline]
fn default() -> Self {
if_tokio_rt!(block: {
return Timer(rt::Time::Timer(Arc::new(wreq_rt::rt::tokio::TokioTimer::new())))
});
if_compio_rt!(block: {
return Timer(rt::Time::Timer(Arc::new(wreq_rt::rt::compio::CompioTimer::new())))
});
if_all_rt!(block: {
return Timer(rt::Time::Timer(Arc::new(wreq_rt::rt::tokio::TokioTimer::new())))
});
if_no_rt!(block: {
Timer(Time::Empty)
})
}
}
impl rt::Timer for Timer {
#[inline]
fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
self.0.sleep(duration)
}
#[inline]
fn now(&self) -> Instant {
self.0.now()
}
#[inline]
fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
self.0.sleep_until(deadline)
}
#[inline]
fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
self.0.reset(sleep, new_deadline)
}
}