@@ -148,10 +148,7 @@ impl Body {
148
148
{
149
149
use http_body_util:: BodyExt ;
150
150
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 ( ) ;
155
152
156
153
Body {
157
154
inner : Inner :: Streaming ( boxed) ,
@@ -461,6 +458,47 @@ where
461
458
}
462
459
}
463
460
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
+
464
502
#[ cfg( test) ]
465
503
mod tests {
466
504
use http_body:: Body as _;
@@ -484,8 +522,9 @@ mod tests {
484
522
assert ! ( !bytes_body. is_end_stream( ) ) ;
485
523
assert_eq ! ( bytes_body. size_hint( ) . exact( ) , Some ( 3 ) ) ;
486
524
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 ) ) ;
490
529
}
491
530
}
0 commit comments