#[cfg(all(unix, feature = "std", feature = "async-io"))]
#[cfg_attr(docsrs, doc(cfg(all(unix, feature = "std", feature = "async-io"))))]
pub mod async_io;
pub mod null;
#[cfg(all(unix, not(miri), feature = "std", feature = "tokio"))]
#[cfg_attr(docsrs, doc(cfg(all(unix, feature = "std", feature = "tokio"))))]
pub mod tokio;
use super::{IoBackend, LinksIoBackend, RefLink};
use core::future::Future;
use core::marker::PhantomData;
pub trait BorrowingFn<B: ?Sized> {
type Fut<'a>: Future
where
B: 'a;
fn call(self, arg: &B) -> Self::Fut<'_>;
}
impl<B: ?Sized, Func: for<'a> FnOnce(&'a B) -> F, F: Future> BorrowingFn<B> for Func {
type Fut<'a> = F where B: 'a;
fn call(self, arg: &B) -> Self::Fut<'_> {
self(arg)
}
}
pub struct UnsafeHrtb<'a, B: ?Sized, Func: FnOnce(&'a B) -> F, F: Future> {
func: Func,
_phantom: PhantomData<fn(&'a B) -> F>,
}
impl<'a, B: ?Sized, Func: FnOnce(&'a B) -> F, F: Future> UnsafeHrtb<'a, B, Func, F> {
unsafe fn new(func: Func) -> Self {
Self {
func,
_phantom: PhantomData,
}
}
}
impl<'a, B: ?Sized, Func: FnOnce(&'a B) -> F, F: Future> BorrowingFn<B>
for UnsafeHrtb<'a, B, Func, F>
{
type Fut<'b> = F where B: 'b;
fn call<'b>(self, arg: &'b B) -> Self::Fut<'b> {
let arg: &'a B = unsafe { &*(arg as *const B) };
(self.func)(arg)
}
}
pub trait Integration: Copy + Default {
type Impl<'a, B: LinksIoBackend + 'a, Func: BorrowingFn<B::Link>>: Future<
Output = <Func::Fut<'a> as Future>::Output,
>;
fn run_with<'a, B: LinksIoBackend + 'a, Func: for<'b> BorrowingFn<B::Link>>(
link: B,
func: Func,
) -> Self::Impl<'a, B, Func>;
fn run_with_mut<'a, B: IoBackend + 'a, Func: FnOnce(&'a B) -> F, F: Future + 'a>(
link: &'a mut B,
func: Func,
) -> Self::Impl<'a, RefLink<'a, B>, UnsafeHrtb<'a, B, Func, F>> {
let func = unsafe { UnsafeHrtb::new(func) };
Self::run_with(RefLink(link), func)
}
}