#![allow(non_snake_case, reason = "macro stuff")]
macro_rules! create_and_implement {
($this:ty, $fn_ty:ident, $fn_fut_ty:ident, ($($tys:ident),*)) => {
impl<$($tys,)* FUN, FUT, RSLT> $fn_fut_ty<($($tys,)*)> for FUN
where
FUN: $fn_ty($($tys,)*) -> FUT,
FUT: Future<Output = RSLT>,
{
type Future = FUT;
type Result = RSLT;
type Wrapper = FnFutWrapper<($($tys,)*), Self>;
#[inline]
fn call(self: $this, ($($tys,)*): ($($tys,)*)) -> Self::Future {
(self)($($tys,)*)
}
#[inline]
fn into_wrapper(self) -> Self::Wrapper {
FnFutWrapper(self, PhantomData)
}
}
};
}
use core::marker::PhantomData;
#[derive(Debug)]
pub struct FnFutWrapper<A, F>(pub(crate) F, pub(crate) PhantomData<A>);
impl<A, F> From<F> for FnFutWrapper<A, F> {
#[inline]
fn from(from: F) -> Self {
Self(from, PhantomData)
}
}
pub trait FnFut<A> {
type Future: Future<Output = Self::Result>;
type Result;
type Wrapper;
fn call(&self, args: A) -> Self::Future;
fn into_wrapper(self) -> Self::Wrapper;
}
create_and_implement!(&Self, Fn, FnFut, ());
create_and_implement!(&Self, Fn, FnFut, (A));
create_and_implement!(&Self, Fn, FnFut, (A, B));
create_and_implement!(&Self, Fn, FnFut, (A, B, C));
create_and_implement!(&Self, Fn, FnFut, (A, B, C, D));
create_and_implement!(&Self, Fn, FnFut, (A, B, C, D, E));
pub trait FnMutFut<A> {
type Future: Future<Output = Self::Result>;
type Result;
type Wrapper;
fn call(&mut self, args: A) -> Self::Future;
fn into_wrapper(self) -> Self::Wrapper;
}
create_and_implement!(&mut Self, FnMut, FnMutFut, ());
create_and_implement!(&mut Self, FnMut, FnMutFut, (A));
create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B));
create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B, C));
create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B, C, D));
create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B, C, D, E));