@@ -482,6 +482,46 @@ impl Body {
482
482
pub fn set_mime ( & mut self , mime : impl Into < Mime > ) {
483
483
self . mime = mime. into ( ) ;
484
484
}
485
+
486
+ /// Create a Body by chaining another Body after this one, consuming both.
487
+ ///
488
+ /// If both Body instances have a length, and their sum does not overflow,
489
+ /// the resulting Body will have a length.
490
+ ///
491
+ /// If both Body instances have the same fallback MIME type, the resulting
492
+ /// Body will have the same fallback MIME type; otherwise, the resulting
493
+ /// Body will have the fallback MIME type `application/octet-stream`.
494
+ ///
495
+ /// # Examples
496
+ ///
497
+ /// ```
498
+ /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
499
+ /// use http_types::Body;
500
+ /// use async_std::io::Cursor;
501
+ ///
502
+ /// let cursor = Cursor::new("Hello ");
503
+ /// let body = Body::from_reader(cursor, None).chain(Body::from("Nori"));
504
+ /// assert_eq!(&body.into_string().await.unwrap(), "Hello Nori");
505
+ /// # Ok(()) }) }
506
+ /// ```
507
+ #[ cfg( feature = "async-std" ) ]
508
+ pub fn chain ( self , other : Body ) -> Self {
509
+ let mime = if self . mime == other. mime {
510
+ self . mime . clone ( )
511
+ } else {
512
+ mime:: BYTE_STREAM
513
+ } ;
514
+ let length = match ( self . length , other. length ) {
515
+ ( Some ( l1) , Some ( l2) ) => ( l1 - self . bytes_read ) . checked_add ( l2 - other. bytes_read ) ,
516
+ _ => None ,
517
+ } ;
518
+ Self {
519
+ mime,
520
+ length,
521
+ reader : Box :: new ( async_std:: io:: ReadExt :: chain ( self , other) ) ,
522
+ bytes_read : 0 ,
523
+ }
524
+ }
485
525
}
486
526
487
527
impl Debug for Body {
@@ -681,4 +721,148 @@ mod test {
681
721
682
722
Ok ( ( ) )
683
723
}
724
+
725
+ #[ async_std:: test]
726
+ async fn chain_strings ( ) -> crate :: Result < ( ) > {
727
+ for buf_len in 1 ..13 {
728
+ let mut body = Body :: from ( "hello " ) . chain ( Body :: from ( "world" ) ) ;
729
+ assert_eq ! ( body. len( ) , Some ( 11 ) ) ;
730
+ assert_eq ! ( body. mime( ) , & mime:: PLAIN ) ;
731
+ assert_eq ! (
732
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
733
+ "hello world"
734
+ ) ;
735
+ assert_eq ! ( body. bytes_read, 11 ) ;
736
+ }
737
+
738
+ Ok ( ( ) )
739
+ }
740
+
741
+ #[ async_std:: test]
742
+ async fn chain_mixed_bytes_string ( ) -> crate :: Result < ( ) > {
743
+ for buf_len in 1 ..13 {
744
+ let mut body = Body :: from ( & b"hello " [ ..] ) . chain ( Body :: from ( "world" ) ) ;
745
+ assert_eq ! ( body. len( ) , Some ( 11 ) ) ;
746
+ assert_eq ! ( body. mime( ) , & mime:: BYTE_STREAM ) ;
747
+ assert_eq ! (
748
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
749
+ "hello world"
750
+ ) ;
751
+ assert_eq ! ( body. bytes_read, 11 ) ;
752
+ }
753
+
754
+ Ok ( ( ) )
755
+ }
756
+
757
+ #[ async_std:: test]
758
+ async fn chain_mixed_reader_string ( ) -> crate :: Result < ( ) > {
759
+ for buf_len in 1 ..13 {
760
+ let mut body =
761
+ Body :: from_reader ( Cursor :: new ( "hello " ) , Some ( 6 ) ) . chain ( Body :: from ( "world" ) ) ;
762
+ assert_eq ! ( body. len( ) , Some ( 11 ) ) ;
763
+ assert_eq ! ( body. mime( ) , & mime:: BYTE_STREAM ) ;
764
+ assert_eq ! (
765
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
766
+ "hello world"
767
+ ) ;
768
+ assert_eq ! ( body. bytes_read, 11 ) ;
769
+ }
770
+
771
+ Ok ( ( ) )
772
+ }
773
+
774
+ #[ async_std:: test]
775
+ async fn chain_mixed_nolen_len ( ) -> crate :: Result < ( ) > {
776
+ for buf_len in 1 ..13 {
777
+ let mut body =
778
+ Body :: from_reader ( Cursor :: new ( "hello " ) , None ) . chain ( Body :: from ( "world" ) ) ;
779
+ assert_eq ! ( body. len( ) , None ) ;
780
+ assert_eq ! ( body. mime( ) , & mime:: BYTE_STREAM ) ;
781
+ assert_eq ! (
782
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
783
+ "hello world"
784
+ ) ;
785
+ assert_eq ! ( body. bytes_read, 11 ) ;
786
+ }
787
+
788
+ Ok ( ( ) )
789
+ }
790
+
791
+ #[ async_std:: test]
792
+ async fn chain_mixed_len_nolen ( ) -> crate :: Result < ( ) > {
793
+ for buf_len in 1 ..13 {
794
+ let mut body =
795
+ Body :: from ( "hello " ) . chain ( Body :: from_reader ( Cursor :: new ( "world" ) , None ) ) ;
796
+ assert_eq ! ( body. len( ) , None ) ;
797
+ assert_eq ! ( body. mime( ) , & mime:: BYTE_STREAM ) ;
798
+ assert_eq ! (
799
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
800
+ "hello world"
801
+ ) ;
802
+ assert_eq ! ( body. bytes_read, 11 ) ;
803
+ }
804
+
805
+ Ok ( ( ) )
806
+ }
807
+
808
+ #[ async_std:: test]
809
+ async fn chain_short ( ) -> crate :: Result < ( ) > {
810
+ for buf_len in 1 ..26 {
811
+ let mut body = Body :: from_reader ( Cursor :: new ( "hello xyz" ) , Some ( 6 ) )
812
+ . chain ( Body :: from_reader ( Cursor :: new ( "world abc" ) , Some ( 5 ) ) ) ;
813
+ assert_eq ! ( body. len( ) , Some ( 11 ) ) ;
814
+ assert_eq ! ( body. mime( ) , & mime:: BYTE_STREAM ) ;
815
+ assert_eq ! (
816
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
817
+ "hello world"
818
+ ) ;
819
+ assert_eq ! ( body. bytes_read, 11 ) ;
820
+ }
821
+
822
+ Ok ( ( ) )
823
+ }
824
+
825
+ #[ async_std:: test]
826
+ async fn chain_many ( ) -> crate :: Result < ( ) > {
827
+ for buf_len in 1 ..13 {
828
+ let mut body = Body :: from ( "hello" )
829
+ . chain ( Body :: from ( & b" " [ ..] ) )
830
+ . chain ( Body :: from ( "world" ) ) ;
831
+ assert_eq ! ( body. len( ) , Some ( 11 ) ) ;
832
+ assert_eq ! ( body. mime( ) , & mime:: BYTE_STREAM ) ;
833
+ assert_eq ! (
834
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
835
+ "hello world"
836
+ ) ;
837
+ assert_eq ! ( body. bytes_read, 11 ) ;
838
+ }
839
+
840
+ Ok ( ( ) )
841
+ }
842
+
843
+ #[ async_std:: test]
844
+ async fn chain_skip_start ( ) -> crate :: Result < ( ) > {
845
+ for buf_len in 1 ..26 {
846
+ let mut body1 = Body :: from_reader ( Cursor :: new ( "1234 hello xyz" ) , Some ( 11 ) ) ;
847
+ let mut buf = vec ! [ 0 ; 5 ] ;
848
+ body1. read ( & mut buf) . await ?;
849
+ assert_eq ! ( buf, b"1234 " ) ;
850
+
851
+ let mut body2 = Body :: from_reader ( Cursor :: new ( "321 world abc" ) , Some ( 9 ) ) ;
852
+ let mut buf = vec ! [ 0 ; 4 ] ;
853
+ body2. read ( & mut buf) . await ?;
854
+ assert_eq ! ( buf, b"321 " ) ;
855
+
856
+ let mut body = body1. chain ( body2) ;
857
+ assert_eq ! ( body. len( ) , Some ( 11 ) ) ;
858
+ assert_eq ! ( body. mime( ) , & mime:: BYTE_STREAM ) ;
859
+ assert_eq ! (
860
+ read_with_buffers_of_size( & mut body, buf_len) . await ?,
861
+ "hello world"
862
+ ) ;
863
+ assert_eq ! ( body. bytes_read, 11 ) ;
864
+ }
865
+
866
+ Ok ( ( ) )
867
+ }
684
868
}
0 commit comments