1use std::future::Future;
28pub trait FnTrait<Args>: Send + Sync {
58 type Output;
59 type Fut: Future<Output = Self::Output> + Send;
60 fn call(&self, args: Args) -> Self::Fut;
61}
62
63macro_rules! impl_fn_trait_for_fn ({ $($param:ident)* } => {
93 impl<Func, Fut, $($param,)*> FnTrait<($($param,)*)> for Func
94 where
95 Func: Fn($($param),*) -> Fut + Send + Sync ,
96 Fut: std::future::Future + Send,
97 {
98 type Output = Fut::Output;
99 type Fut = Fut;
100
101 #[inline]
102 #[allow(non_snake_case)]
103 fn call(&self, ($($param,)*): ($($param,)*)) -> Self::Fut {
104 (self)($($param,)*)
105 }
106 }
107});
108
109impl_fn_trait_for_fn! {}
110impl_fn_trait_for_fn! { A }
111impl_fn_trait_for_fn! { A B }
112impl_fn_trait_for_fn! { A B C }
113impl_fn_trait_for_fn! { A B C D }
114impl_fn_trait_for_fn! { A B C D E }
115impl_fn_trait_for_fn! { A B C D E F }
116impl_fn_trait_for_fn! { A B C D E F G }
117impl_fn_trait_for_fn! { A B C D E F G H }
118impl_fn_trait_for_fn! { A B C D E F G H I }
119impl_fn_trait_for_fn! { A B C D E F G H I J }
120impl_fn_trait_for_fn! { A B C D E F G H I J K }
121impl_fn_trait_for_fn! { A B C D E F G H I J K L }
122
123#[cfg(test)]
124mod tests {
125 use crate::fn_trait::FnTrait;
126 use http::{HeaderMap, Method};
127
128 fn assert_is_fn_trait<Args, F: FnTrait<Args>>(_f: F) {
129 }
131 async fn foo0() {}
132 async fn foo1(_a: ()) {}
133 async fn foo2(_a1: &Method, _a2: &HeaderMap) {}
134 async fn foo3(_a1: &Method, _a2: &HeaderMap, _a3: ()) {}
135 async fn foo4(_a1: &Method, _a2: &HeaderMap, _a3: (), _a4: ()) {}
136 async fn foo5(_a1: (), _a2: &HeaderMap, _a3: (), _a4: (), _a5: ()) {}
137 async fn foo6(_a1: (), _a2: &HeaderMap, _a3: (), _a4: (), _a5: (), _a6: ()) {}
138 async fn foo7(_a1: &Method, _a2: (), _a3: (), _a4: (), _a5: (), _a6: (), _a7: ()) {}
139 #[allow(clippy::too_many_arguments)]
140 async fn foo8(_a1: &Method, _a2: &HeaderMap, _a3: (), _a4: (), _a5: (), _a6: (), _a7: (), _a8: ()) {}
141 #[allow(clippy::too_many_arguments)]
142 async fn foo9(_a1: &Method, _a2: (), _a3: (), _a4: (), _a5: (), _a6: (), _a7: (), _a8: (), _a9: ()) {}
143 #[allow(clippy::too_many_arguments)]
144 async fn foo10(_a1: &Method, _a2: &HeaderMap, _a3: (), _a4: (), _a5: (), _a6: (), _a7: (), _a8: (), _a9: (), _a10: ()) {}
145 #[allow(clippy::too_many_arguments)]
146 async fn foo11(_a1: &Method, _a2: &HeaderMap, _a3: (), _a4: (), _a5: (), _a6: (), _a7: (), _a8: (), _a9: (), _a10: (), _a11: ()) {}
147 #[allow(clippy::too_many_arguments)]
148 async fn foo12(
149 _a1: &Method,
150 _a2: &HeaderMap,
151 _a3: (),
152 _a4: (),
153 _a5: (),
154 _a6: (),
155 _a7: (),
156 _a8: (),
157 _a9: (),
158 _a10: (),
159 _a11: (),
160 _a12: (),
161 ) {
162 }
163
164 #[test]
165 fn test_fn_is_fn_trait() {
166 assert_is_fn_trait(foo0);
167 assert_is_fn_trait(foo1);
168 assert_is_fn_trait(foo2);
169 assert_is_fn_trait(foo3);
170 assert_is_fn_trait(foo4);
171 assert_is_fn_trait(foo5);
172 assert_is_fn_trait(foo6);
173 assert_is_fn_trait(foo7);
174 assert_is_fn_trait(foo8);
175 assert_is_fn_trait(foo9);
176 assert_is_fn_trait(foo10);
177 assert_is_fn_trait(foo11);
178 assert_is_fn_trait(foo12);
179 }
180}