4848
4949use std:: error:: Error as StdError ;
5050use std:: fmt;
51- #[ cfg( feature = "http2" ) ]
51+ #[ cfg( not ( all ( feature = "http1" , feature = " http2") ) ) ]
5252use std:: marker:: PhantomData ;
5353use std:: sync:: Arc ;
5454#[ cfg( all( feature = "runtime" , feature = "http2" ) ) ]
@@ -57,12 +57,14 @@ use std::time::Duration;
5757use bytes:: Bytes ;
5858use futures_util:: future:: { self , Either , FutureExt as _} ;
5959use httparse:: ParserConfig ;
60- use pin_project :: pin_project;
60+ use pin_project_lite :: pin_project;
6161use tokio:: io:: { AsyncRead , AsyncWrite } ;
6262use tower_service:: Service ;
6363
6464use super :: dispatch;
6565use crate :: body:: HttpBody ;
66+ #[ cfg( not( all( feature = "http1" , feature = "http2" ) ) ) ]
67+ use crate :: common:: Never ;
6668use crate :: common:: {
6769 exec:: { BoxSendFuture , Exec } ,
6870 task, Future , Pin , Poll ,
@@ -74,17 +76,33 @@ use crate::upgrade::Upgraded;
7476use crate :: { Body , Request , Response } ;
7577
7678#[ cfg( feature = "http1" ) ]
77- type Http1Dispatcher < T , B , R > = proto:: dispatch:: Dispatcher < proto:: dispatch:: Client < B > , B , T , R > ;
79+ type Http1Dispatcher < T , B > =
80+ proto:: dispatch:: Dispatcher < proto:: dispatch:: Client < B > , B , T , proto:: h1:: ClientTransaction > ;
7881
79- #[ pin_project( project = ProtoClientProj ) ]
80- enum ProtoClient < T , B >
81- where
82- B : HttpBody ,
83- {
84- #[ cfg( feature = "http1" ) ]
85- H1 ( #[ pin] Http1Dispatcher < T , B , proto:: h1:: ClientTransaction > ) ,
86- #[ cfg( feature = "http2" ) ]
87- H2 ( #[ pin] proto:: h2:: ClientTask < B > , PhantomData < fn ( T ) > ) ,
82+ #[ cfg( not( feature = "http1" ) ) ]
83+ type Http1Dispatcher < T , B > = ( Never , PhantomData < ( T , Pin < Box < B > > ) > ) ;
84+
85+ #[ cfg( feature = "http2" ) ]
86+ type Http2ClientTask < B > = proto:: h2:: ClientTask < B > ;
87+
88+ #[ cfg( not( feature = "http2" ) ) ]
89+ type Http2ClientTask < B > = ( Never , PhantomData < Pin < Box < B > > > ) ;
90+
91+ pin_project ! {
92+ #[ project = ProtoClientProj ]
93+ enum ProtoClient <T , B >
94+ where
95+ B : HttpBody ,
96+ {
97+ H1 {
98+ #[ pin]
99+ h1: Http1Dispatcher <T , B >,
100+ } ,
101+ H2 {
102+ #[ pin]
103+ h2: Http2ClientTask <B >,
104+ } ,
105+ }
88106}
89107
90108/// Returns a handshake future over some IO.
@@ -405,18 +423,20 @@ where
405423 pub fn into_parts ( self ) -> Parts < T > {
406424 match self . inner . expect ( "already upgraded" ) {
407425 #[ cfg( feature = "http1" ) ]
408- ProtoClient :: H1 ( h1 ) => {
426+ ProtoClient :: H1 { h1 } => {
409427 let ( io, read_buf, _) = h1. into_inner ( ) ;
410428 Parts {
411429 io,
412430 read_buf,
413431 _inner : ( ) ,
414432 }
415433 }
416- #[ cfg( feature = "http2" ) ]
417- ProtoClient :: H2 ( ..) => {
434+ ProtoClient :: H2 { .. } => {
418435 panic ! ( "http2 cannot into_inner" ) ;
419436 }
437+
438+ #[ cfg( not( feature = "http1" ) ) ]
439+ ProtoClient :: H1 { h1 } => match h1. 0 { } ,
420440 }
421441 }
422442
@@ -434,9 +454,14 @@ where
434454 pub fn poll_without_shutdown ( & mut self , cx : & mut task:: Context < ' _ > ) -> Poll < crate :: Result < ( ) > > {
435455 match * self . inner . as_mut ( ) . expect ( "already upgraded" ) {
436456 #[ cfg( feature = "http1" ) ]
437- ProtoClient :: H1 ( ref mut h1) => h1. poll_without_shutdown ( cx) ,
457+ ProtoClient :: H1 { ref mut h1 } => h1. poll_without_shutdown ( cx) ,
438458 #[ cfg( feature = "http2" ) ]
439- ProtoClient :: H2 ( ref mut h2, _) => Pin :: new ( h2) . poll ( cx) . map_ok ( |_| ( ) ) ,
459+ ProtoClient :: H2 { ref mut h2, .. } => Pin :: new ( h2) . poll ( cx) . map_ok ( |_| ( ) ) ,
460+
461+ #[ cfg( not( feature = "http1" ) ) ]
462+ ProtoClient :: H1 { ref mut h1 } => match h1. 0 { } ,
463+ #[ cfg( not( feature = "http2" ) ) ]
464+ ProtoClient :: H2 { ref mut h2, .. } => match h2. 0 { } ,
440465 }
441466 }
442467
@@ -465,7 +490,7 @@ where
465490 proto:: Dispatched :: Shutdown => Poll :: Ready ( Ok ( ( ) ) ) ,
466491 #[ cfg( feature = "http1" ) ]
467492 proto:: Dispatched :: Upgrade ( pending) => match self . inner . take ( ) {
468- Some ( ProtoClient :: H1 ( h1 ) ) => {
493+ Some ( ProtoClient :: H1 { h1 } ) => {
469494 let ( io, buf, _) = h1. into_inner ( ) ;
470495 pending. fulfill ( Upgraded :: new ( io, buf) ) ;
471496 Poll :: Ready ( Ok ( ( ) ) )
@@ -756,14 +781,14 @@ impl Builder {
756781 }
757782 let cd = proto:: h1:: dispatch:: Client :: new ( rx) ;
758783 let dispatch = proto:: h1:: Dispatcher :: new ( cd, conn) ;
759- ProtoClient :: H1 ( dispatch)
784+ ProtoClient :: H1 { h1 : dispatch }
760785 }
761786 #[ cfg( feature = "http2" ) ]
762787 Proto :: Http2 => {
763788 let h2 =
764789 proto:: h2:: client:: handshake ( io, rx, & opts. h2_builder , opts. exec . clone ( ) )
765790 . await ?;
766- ProtoClient :: H2 ( h2 , PhantomData )
791+ ProtoClient :: H2 { h2 }
767792 }
768793 } ;
769794
@@ -817,9 +842,14 @@ where
817842 fn poll ( self : Pin < & mut Self > , cx : & mut task:: Context < ' _ > ) -> Poll < Self :: Output > {
818843 match self . project ( ) {
819844 #[ cfg( feature = "http1" ) ]
820- ProtoClientProj :: H1 ( c ) => c . poll ( cx) ,
845+ ProtoClientProj :: H1 { h1 } => h1 . poll ( cx) ,
821846 #[ cfg( feature = "http2" ) ]
822- ProtoClientProj :: H2 ( c, _) => c. poll ( cx) ,
847+ ProtoClientProj :: H2 { h2, .. } => h2. poll ( cx) ,
848+
849+ #[ cfg( not( feature = "http1" ) ) ]
850+ ProtoClientProj :: H1 { h1 } => match h1. 0 { } ,
851+ #[ cfg( not( feature = "http2" ) ) ]
852+ ProtoClientProj :: H2 { h2, .. } => match h2. 0 { } ,
823853 }
824854 }
825855}
0 commit comments