@@ -5,7 +5,6 @@ use bytes::Bytes;
55use fast_pull:: { ProgressEntry , RandPuller , SeqPuller } ;
66use futures:: { Stream , TryFutureExt , TryStream } ;
77use std:: {
8- marker:: PhantomData ,
98 pin:: { Pin , pin} ,
109 task:: { Context , Poll } ,
1110} ;
@@ -22,6 +21,14 @@ impl<Client: HttpClient> HttpPuller<Client> {
2221 }
2322}
2423
24+ type ResponseFut < Client > =
25+ Pin < Box < dyn Future < Output = Result < GetResponse < Client > , GetRequestError < Client > > > + Send > > ;
26+ enum ResponseState < Client : HttpClient > {
27+ Pending ( ResponseFut < Client > ) ,
28+ Ready ( GetResponse < Client > ) ,
29+ None ,
30+ }
31+
2532impl < Client : HttpClient + ' static > RandPuller for HttpPuller < Client > {
2633 type Error = HttpError < Client > ;
2734 fn pull (
@@ -37,13 +44,6 @@ impl<Client: HttpClient + 'static> RandPuller for HttpPuller<Client> {
3744 }
3845 }
3946}
40- type ResponseFut < Client > =
41- Pin < Box < dyn Future < Output = Result < GetResponse < Client > , GetRequestError < Client > > > + Send > > ;
42- enum ResponseState < Client : HttpClient > {
43- Pending ( ResponseFut < Client > ) ,
44- Ready ( GetResponse < Client > ) ,
45- None ,
46- }
4747struct RandRequestStream < Client : HttpClient + ' static > {
4848 client : Client ,
4949 url : Url ,
@@ -107,38 +107,50 @@ impl<Client: HttpClient + 'static> SeqPuller for HttpPuller<Client> {
107107 fn pull ( & mut self ) -> impl TryStream < Ok = Bytes , Error = Self :: Error > + Send + Unpin {
108108 let req = self . client . get ( self . url . clone ( ) , None ) . send ( ) ;
109109 SeqRequestStream {
110- resp : Box :: pin ( req) ,
111- _client : PhantomData ,
110+ state : ResponseState :: Pending ( Box :: pin ( req) ) ,
112111 }
113112 }
114113}
115- struct SeqRequestStream < Client : HttpClient + ' static , Fut >
116- where
117- Fut : Future < Output = Result < GetResponse < Client > , GetRequestError < Client > > > + Unpin ,
118- {
119- _client : PhantomData < Client > ,
120- resp : Fut ,
114+ struct SeqRequestStream < Client : HttpClient + ' static > {
115+ state : ResponseState < Client > ,
121116}
122- impl < Client : HttpClient , Fut > Stream for SeqRequestStream < Client , Fut >
123- where
124- Fut : Future < Output = Result < GetResponse < Client > , GetRequestError < Client > > > + Unpin ,
125- {
117+ impl < Client : HttpClient > Stream for SeqRequestStream < Client > {
126118 type Item = Result < Bytes , HttpError < Client > > ;
127119 fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
128- let mut response;
129- match self . resp . try_poll_unpin ( cx) {
130- Poll :: Ready ( resp) => match resp {
131- Ok ( resp) => response = resp,
132- Err ( e) => return Poll :: Ready ( Some ( Err ( HttpError :: Request ( e) ) ) ) ,
133- } ,
134- Poll :: Pending => return Poll :: Pending ,
120+ let chunk_global;
121+ match & mut self . state {
122+ ResponseState :: Pending ( resp) => {
123+ return match resp. try_poll_unpin ( cx) {
124+ Poll :: Ready ( resp) => match resp {
125+ Ok ( resp) => {
126+ self . state = ResponseState :: Ready ( resp) ;
127+ self . poll_next ( cx)
128+ }
129+ Err ( e) => {
130+ self . state = ResponseState :: None ;
131+ Poll :: Ready ( Some ( Err ( HttpError :: Request ( e) ) ) )
132+ }
133+ } ,
134+ Poll :: Pending => Poll :: Pending ,
135+ } ;
136+ }
137+ ResponseState :: None => return Poll :: Ready ( Some ( Err ( HttpError :: Irrecoverable ) ) ) ,
138+ ResponseState :: Ready ( resp) => {
139+ let mut chunk = pin ! ( resp. chunk( ) ) ;
140+ match chunk. try_poll_unpin ( cx) {
141+ Poll :: Ready ( Ok ( Some ( chunk) ) ) => chunk_global = Ok ( chunk) ,
142+ Poll :: Ready ( Ok ( None ) ) => return Poll :: Ready ( None ) ,
143+ Poll :: Ready ( Err ( e) ) => chunk_global = Err ( e) ,
144+ Poll :: Pending => return Poll :: Pending ,
145+ } ;
146+ }
135147 } ;
136- let mut chunk = pin ! ( response . chunk ( ) ) ;
137- match chunk . try_poll_unpin ( cx ) {
138- Poll :: Ready ( Ok ( Some ( chunk ) ) ) => Poll :: Ready ( Some ( Ok ( chunk ) ) ) ,
139- Poll :: Ready ( Ok ( None ) ) => Poll :: Ready ( None ) ,
140- Poll :: Ready ( Err ( e ) ) => Poll :: Ready ( Some ( Err ( HttpError :: Chunk ( e) ) ) ) ,
141- Poll :: Pending => Poll :: Pending ,
148+ match chunk_global {
149+ Ok ( chunk ) => Poll :: Ready ( Some ( Ok ( chunk ) ) ) ,
150+ Err ( e ) => {
151+ self . state = ResponseState :: None ;
152+ Poll :: Ready ( Some ( Err ( HttpError :: Chunk ( e) ) ) )
153+ }
142154 }
143155 }
144156}
0 commit comments