1 //! [`Future`] types
2 //!
3 //! [`Future`]: std::future::Future
4 use futures_core::ready;
5 use pin_project_lite::pin_project;
6 use std::{
7     future::Future,
8     pin::Pin,
9     task::{Context, Poll},
10 };
11 use tokio::sync::OwnedSemaphorePermit;
12 
13 pin_project! {
14     /// Future for the [`ConcurrencyLimit`] service.
15     ///
16     /// [`ConcurrencyLimit`]: crate::limit::ConcurrencyLimit
17     #[derive(Debug)]
18     pub struct ResponseFuture<T> {
19         #[pin]
20         inner: T,
21         // Keep this around so that it is dropped when the future completes
22         _permit: OwnedSemaphorePermit,
23     }
24 }
25 
26 impl<T> ResponseFuture<T> {
new(inner: T, _permit: OwnedSemaphorePermit) -> ResponseFuture<T>27     pub(crate) fn new(inner: T, _permit: OwnedSemaphorePermit) -> ResponseFuture<T> {
28         ResponseFuture { inner, _permit }
29     }
30 }
31 
32 impl<F, T, E> Future for ResponseFuture<F>
33 where
34     F: Future<Output = Result<T, E>>,
35 {
36     type Output = Result<T, E>;
37 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>38     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
39         Poll::Ready(ready!(self.project().inner.poll(cx)))
40     }
41 }
42