Skip to content

Commit 9645a12

Browse files
committed
refactor(client): return HttpConnecting newtype
1 parent 30ac01c commit 9645a12

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

src/client/connect/http.rs

+34-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::error::Error as StdError;
22
use std::future::Future;
3+
use std::marker::PhantomData;
34
use std::pin::Pin;
45
use std::task::{self, Poll};
56
use std::fmt;
@@ -11,13 +12,15 @@ use std::time::Duration;
1112
use futures_util::future::Either;
1213
use http::uri::{Scheme, Uri};
1314
use net2::TcpBuilder;
15+
use pin_project::pin_project;
1416
use tokio::net::TcpStream;
1517
use tokio::time::Delay;
1618

1719
use super::dns::{self, resolve, GaiResolver, Resolve};
1820
use super::{Connected, Destination};
1921
//#[cfg(feature = "runtime")] use super::dns::TokioThreadpoolGaiResolver;
2022

23+
2124
/// A connector for the `http` scheme.
2225
///
2326
/// Performs DNS resolution in a thread pool, and then connects over TCP.
@@ -233,8 +236,7 @@ where
233236
{
234237
type Response = (TcpStream, Connected);
235238
type Error = ConnectError;
236-
type Future =
237-
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
239+
type Future = HttpConnecting<R>;
238240

239241
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
240242
ready!(self.resolver.poll_ready(cx)).map_err(ConnectError::dns)?;
@@ -243,7 +245,10 @@ where
243245

244246
fn call(&mut self, dst: Destination) -> Self::Future {
245247
let mut self_ = self.clone();
246-
Box::pin(async move { self_.call_async(dst).await })
248+
HttpConnecting {
249+
fut: Box::pin(async move { self_.call_async(dst).await }),
250+
_marker: PhantomData,
251+
}
247252
}
248253
}
249254

@@ -373,6 +378,32 @@ impl HttpInfo {
373378
}
374379
}
375380

381+
// Not publicly exported (so missing_docs doesn't trigger).
382+
//
383+
// We return this `Future` instead of the `Pin<Box<dyn Future>>` directly
384+
// so that users don't rely on it fitting in a `Pin<Box<dyn Future>>` slot
385+
// (and thus we can change the type in the future).
386+
#[must_use = "futures do nothing unless polled"]
387+
#[pin_project]
388+
#[allow(missing_debug_implementations)]
389+
pub struct HttpConnecting<R> {
390+
#[pin]
391+
fut: BoxConnecting,
392+
_marker: PhantomData<R>,
393+
}
394+
395+
type ConnectResult = Result<(TcpStream, Connected), ConnectError>;
396+
type BoxConnecting = Pin<Box<dyn Future<Output = ConnectResult> + Send>>;
397+
398+
impl<R: Resolve> Future for HttpConnecting<R> {
399+
type Output = ConnectResult;
400+
401+
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
402+
self.project().fut.poll(cx)
403+
}
404+
}
405+
406+
376407
// Not publicly exported (so missing_docs doesn't trigger).
377408
pub struct ConnectError {
378409
msg: Box<str>,

0 commit comments

Comments
 (0)