@@ -148,10 +148,7 @@ impl Body {
148148 {
149149 use http_body_util:: BodyExt ;
150150
151- let boxed = inner
152- . map_frame ( |f| f. map_data ( Into :: into) )
153- . map_err ( Into :: into)
154- . boxed ( ) ;
151+ let boxed = IntoBytesBody { inner } . map_err ( Into :: into) . boxed ( ) ;
155152
156153 Body {
157154 inner : Inner :: Streaming ( boxed) ,
@@ -461,6 +458,47 @@ where
461458 }
462459}
463460
461+ // ===== impl IntoBytesBody =====
462+
463+ pin_project ! {
464+ struct IntoBytesBody <B > {
465+ #[ pin]
466+ inner: B ,
467+ }
468+ }
469+
470+ // We can't use `map_frame()` because that loses the hint data (for good reason).
471+ // But we aren't transforming the data.
472+ impl < B > hyper:: body:: Body for IntoBytesBody < B >
473+ where
474+ B : hyper:: body:: Body ,
475+ B :: Data : Into < Bytes > ,
476+ {
477+ type Data = Bytes ;
478+ type Error = B :: Error ;
479+
480+ fn poll_frame (
481+ self : Pin < & mut Self > ,
482+ cx : & mut Context ,
483+ ) -> Poll < Option < Result < hyper:: body:: Frame < Self :: Data > , Self :: Error > > > {
484+ match futures_core:: ready!( self . project( ) . inner. poll_frame( cx) ) {
485+ Some ( Ok ( f) ) => Poll :: Ready ( Some ( Ok ( f. map_data ( Into :: into) ) ) ) ,
486+ Some ( Err ( e) ) => Poll :: Ready ( Some ( Err ( e) ) ) ,
487+ None => Poll :: Ready ( None ) ,
488+ }
489+ }
490+
491+ #[ inline]
492+ fn size_hint ( & self ) -> http_body:: SizeHint {
493+ self . inner . size_hint ( )
494+ }
495+
496+ #[ inline]
497+ fn is_end_stream ( & self ) -> bool {
498+ self . inner . is_end_stream ( )
499+ }
500+ }
501+
464502#[ cfg( test) ]
465503mod tests {
466504 use http_body:: Body as _;
@@ -484,8 +522,9 @@ mod tests {
484522 assert ! ( !bytes_body. is_end_stream( ) ) ;
485523 assert_eq ! ( bytes_body. size_hint( ) . exact( ) , Some ( 3 ) ) ;
486524
487- let stream_body = Body :: wrap ( bytes_body) ;
488- assert ! ( !stream_body. is_end_stream( ) ) ;
489- assert_eq ! ( stream_body. size_hint( ) . exact( ) , None ) ;
525+ // can delegate even when wrapped
526+ let stream_body = Body :: wrap ( empty_body) ;
527+ assert ! ( stream_body. is_end_stream( ) ) ;
528+ assert_eq ! ( stream_body. size_hint( ) . exact( ) , Some ( 0 ) ) ;
490529 }
491530}
0 commit comments