4848
4949use std:: error:: Error as StdError ;
5050use std:: fmt;
51- #[ cfg( feature = "http2" ) ]
52- use std:: marker:: PhantomData ;
5351use std:: sync:: Arc ;
5452#[ cfg( all( feature = "runtime" , feature = "http2" ) ) ]
5553use std:: time:: Duration ;
5654
5755use bytes:: Bytes ;
5856use futures_util:: future:: { self , Either , FutureExt as _} ;
5957use httparse:: ParserConfig ;
60- use pin_project :: pin_project;
58+ use pin_project_lite :: pin_project;
6159use tokio:: io:: { AsyncRead , AsyncWrite } ;
6260use tower_service:: Service ;
6361
6462use super :: dispatch;
63+ #[ cfg( not( all( feature = "http1" , feature = "http2" ) ) ) ]
64+ use crate :: common:: Never ;
6565use crate :: body:: HttpBody ;
6666use crate :: common:: {
6767 exec:: { BoxSendFuture , Exec } ,
@@ -74,17 +74,33 @@ use crate::upgrade::Upgraded;
7474use crate :: { Body , Request , Response } ;
7575
7676#[ cfg( feature = "http1" ) ]
77- type Http1Dispatcher < T , B , R > = proto:: dispatch:: Dispatcher < proto:: dispatch:: Client < B > , B , T , R > ;
77+ type Http1Dispatcher < T , B > =
78+ proto:: dispatch:: Dispatcher < proto:: dispatch:: Client < B > , B , T , proto:: h1:: ClientTransaction > ;
7879
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 ) > ) ,
80+ #[ cfg( not( feature = "http1" ) ) ]
81+ type Http1Dispatcher < T , B > = ( Never , T , Pin < Box < B > > ) ;
82+
83+ #[ cfg( feature = "http2" ) ]
84+ type Http2ClientTask < B > = proto:: h2:: ClientTask < B > ;
85+
86+ #[ cfg( not( feature = "http2" ) ) ]
87+ type Http2ClientTask < B > = ( Never , Pin < Box < B > > ) ;
88+
89+ pin_project ! {
90+ #[ project = ProtoClientProj ]
91+ enum ProtoClient <T , B >
92+ where
93+ B : HttpBody ,
94+ {
95+ H1 {
96+ #[ pin]
97+ h1: Http1Dispatcher <T , B >,
98+ } ,
99+ H2 {
100+ #[ pin]
101+ h2: Http2ClientTask <B >,
102+ } ,
103+ }
88104}
89105
90106/// Returns a handshake future over some IO.
@@ -405,18 +421,20 @@ where
405421 pub fn into_parts ( self ) -> Parts < T > {
406422 match self . inner . expect ( "already upgraded" ) {
407423 #[ cfg( feature = "http1" ) ]
408- ProtoClient :: H1 ( h1 ) => {
424+ ProtoClient :: H1 { h1 } => {
409425 let ( io, read_buf, _) = h1. into_inner ( ) ;
410426 Parts {
411427 io,
412428 read_buf,
413429 _inner : ( ) ,
414430 }
415431 }
416- #[ cfg( feature = "http2" ) ]
417- ProtoClient :: H2 ( ..) => {
432+ ProtoClient :: H2 { .. } => {
418433 panic ! ( "http2 cannot into_inner" ) ;
419434 }
435+
436+ #[ cfg( not( feature = "http1" ) ) ]
437+ ProtoClient :: H1 { h1 } => match h1. 0 { } ,
420438 }
421439 }
422440
@@ -434,9 +452,14 @@ where
434452 pub fn poll_without_shutdown ( & mut self , cx : & mut task:: Context < ' _ > ) -> Poll < crate :: Result < ( ) > > {
435453 match * self . inner . as_mut ( ) . expect ( "already upgraded" ) {
436454 #[ cfg( feature = "http1" ) ]
437- ProtoClient :: H1 ( ref mut h1) => h1. poll_without_shutdown ( cx) ,
455+ ProtoClient :: H1 { ref mut h1 } => h1. poll_without_shutdown ( cx) ,
438456 #[ cfg( feature = "http2" ) ]
439- ProtoClient :: H2 ( ref mut h2, _) => Pin :: new ( h2) . poll ( cx) . map_ok ( |_| ( ) ) ,
457+ ProtoClient :: H2 { ref mut h2, .. } => Pin :: new ( h2) . poll ( cx) . map_ok ( |_| ( ) ) ,
458+
459+ #[ cfg( not( feature = "http1" ) ) ]
460+ ProtoClient :: H1 { ref mut h1 } => match h1. 0 { } ,
461+ #[ cfg( not( feature = "http2" ) ) ]
462+ ProtoClient :: H2 { ref mut h2, .. } => match h2. 0 { } ,
440463 }
441464 }
442465
@@ -465,7 +488,7 @@ where
465488 proto:: Dispatched :: Shutdown => Poll :: Ready ( Ok ( ( ) ) ) ,
466489 #[ cfg( feature = "http1" ) ]
467490 proto:: Dispatched :: Upgrade ( pending) => match self . inner . take ( ) {
468- Some ( ProtoClient :: H1 ( h1 ) ) => {
491+ Some ( ProtoClient :: H1 { h1 } ) => {
469492 let ( io, buf, _) = h1. into_inner ( ) ;
470493 pending. fulfill ( Upgraded :: new ( io, buf) ) ;
471494 Poll :: Ready ( Ok ( ( ) ) )
@@ -756,14 +779,14 @@ impl Builder {
756779 }
757780 let cd = proto:: h1:: dispatch:: Client :: new ( rx) ;
758781 let dispatch = proto:: h1:: Dispatcher :: new ( cd, conn) ;
759- ProtoClient :: H1 ( dispatch)
782+ ProtoClient :: H1 { h1 : dispatch }
760783 }
761784 #[ cfg( feature = "http2" ) ]
762785 Proto :: Http2 => {
763786 let h2 =
764787 proto:: h2:: client:: handshake ( io, rx, & opts. h2_builder , opts. exec . clone ( ) )
765788 . await ?;
766- ProtoClient :: H2 ( h2 , PhantomData )
789+ ProtoClient :: H2 { h2 }
767790 }
768791 } ;
769792
@@ -817,9 +840,14 @@ where
817840 fn poll ( self : Pin < & mut Self > , cx : & mut task:: Context < ' _ > ) -> Poll < Self :: Output > {
818841 match self . project ( ) {
819842 #[ cfg( feature = "http1" ) ]
820- ProtoClientProj :: H1 ( c ) => c . poll ( cx) ,
843+ ProtoClientProj :: H1 { h1 } => h1 . poll ( cx) ,
821844 #[ cfg( feature = "http2" ) ]
822- ProtoClientProj :: H2 ( c, _) => c. poll ( cx) ,
845+ ProtoClientProj :: H2 { h2, .. } => h2. poll ( cx) ,
846+
847+ #[ cfg( not( feature = "http1" ) ) ]
848+ ProtoClientProj :: H1 { h1 } => match h1. 0 { } ,
849+ #[ cfg( not( feature = "http2" ) ) ]
850+ ProtoClientProj :: H2 { h2, .. } => match h2. 0 { } ,
823851 }
824852 }
825853}
0 commit comments