@@ -2,7 +2,7 @@ use std::{
2
2
borrow:: Cow ,
3
3
cmp:: { Ordering , min} ,
4
4
fmt,
5
- io:: { BufRead , Read , Result as IoResult , Write } ,
5
+ io:: { BufRead , Cursor , Read , Result as IoResult , Write } ,
6
6
mem,
7
7
ops:: { AddAssign , Deref } ,
8
8
pin:: Pin ,
@@ -48,7 +48,7 @@ struct InnerRope(Arc<[RopeElem]>);
48
48
#[ derive( Clone , Debug ) ]
49
49
enum RopeElem {
50
50
/// Local bytes are owned directly by this rope.
51
- Local ( Bytes ) ,
51
+ Local ( Cow < ' static , [ u8 ] > ) ,
52
52
53
53
/// Shared holds the Arc container of another rope.
54
54
Shared ( InnerRope ) ,
@@ -122,21 +122,24 @@ impl Rope {
122
122
impl From < Vec < u8 > > for Rope {
123
123
fn from ( mut bytes : Vec < u8 > ) -> Self {
124
124
bytes. shrink_to_fit ( ) ;
125
- Rope :: from ( Bytes :: from ( bytes) )
125
+ Rope :: from ( Cow :: Owned ( bytes) )
126
126
}
127
127
}
128
128
129
129
impl From < String > for Rope {
130
- fn from ( mut bytes : String ) -> Self {
131
- bytes. shrink_to_fit ( ) ;
132
- Rope :: from ( Bytes :: from ( bytes) )
130
+ fn from ( bytes : String ) -> Self {
131
+ Rope :: from ( bytes. into_bytes ( ) )
133
132
}
134
133
}
135
134
136
- impl < T : Into < Bytes > > From < T > for Rope {
137
- default fn from ( bytes : T ) -> Self {
138
- let bytes = bytes. into ( ) ;
139
- // We can't have an InnerRope which contains an empty Local section.
135
+ impl From < & ' static str > for Rope {
136
+ fn from ( bytes : & ' static str ) -> Self {
137
+ Rope :: from ( Cow :: Borrowed ( bytes. as_bytes ( ) ) )
138
+ }
139
+ }
140
+
141
+ impl From < Cow < ' static , [ u8 ] > > for Rope {
142
+ fn from ( bytes : Cow < ' static , [ u8 ] > ) -> Self {
140
143
if bytes. is_empty ( ) {
141
144
Default :: default ( )
142
145
} else {
@@ -181,7 +184,7 @@ impl RopeBuilder {
181
184
self . finish ( ) ;
182
185
183
186
self . length += bytes. len ( ) ;
184
- self . committed . push ( Local ( Bytes :: from_static ( bytes) ) ) ;
187
+ self . committed . push ( Local ( Cow :: Borrowed ( bytes) ) ) ;
185
188
}
186
189
187
190
/// Concatenate another Rope instance into our builder.
@@ -320,10 +323,10 @@ impl Uncommitted {
320
323
321
324
/// Converts the current uncommitted bytes into a Bytes, resetting our
322
325
/// representation to None.
323
- fn finish ( & mut self ) -> Option < Bytes > {
326
+ fn finish ( & mut self ) -> Option < Cow < ' static , [ u8 ] > > {
324
327
match mem:: take ( self ) {
325
328
Self :: None => None ,
326
- Self :: Static ( s) => Some ( Bytes :: from_static ( s) ) ,
329
+ Self :: Static ( s) => Some ( Cow :: Borrowed ( s) ) ,
327
330
Self :: Owned ( mut v) => {
328
331
v. shrink_to_fit ( ) ;
329
332
Some ( v. into ( ) )
@@ -336,10 +339,7 @@ impl fmt::Debug for Uncommitted {
336
339
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
337
340
match self {
338
341
Uncommitted :: None => f. write_str ( "None" ) ,
339
- Uncommitted :: Static ( s) => f
340
- . debug_tuple ( "Static" )
341
- . field ( & Bytes :: from_static ( s) )
342
- . finish ( ) ,
342
+ Uncommitted :: Static ( s) => f. debug_tuple ( "Static" ) . field ( & Cow :: Borrowed ( s) ) . finish ( ) ,
343
343
Uncommitted :: Owned ( v) => f
344
344
. debug_tuple ( "Owned" )
345
345
. field ( & Bytes :: from ( v. clone ( ) ) )
@@ -637,7 +637,7 @@ pub struct RopeReader {
637
637
/// continue onto the next item in the stack.
638
638
#[ derive( Debug ) ]
639
639
enum StackElem {
640
- Local ( Bytes ) ,
640
+ Local ( Cursor < Cow < ' static , [ u8 ] > > ) ,
641
641
Shared ( InnerRope , usize ) ,
642
642
}
643
643
@@ -660,14 +660,14 @@ impl RopeReader {
660
660
while remaining > 0 {
661
661
let mut bytes = match self . next ( ) {
662
662
None => break ,
663
- Some ( b) => b ,
663
+ Some ( b) => Cursor :: new ( b ) ,
664
664
} ;
665
665
666
- let amount = min ( bytes. len ( ) , remaining) ;
666
+ let amount = min ( bytes. get_ref ( ) . len ( ) , remaining) ;
667
667
668
- buf. put_slice ( & bytes[ 0 ..amount] ) ;
668
+ buf. put_slice ( & bytes. get_ref ( ) [ 0 ..amount] ) ;
669
669
670
- if amount < bytes. len ( ) {
670
+ if amount < bytes. get_ref ( ) . len ( ) {
671
671
bytes. advance ( amount) ;
672
672
self . stack . push ( StackElem :: Local ( bytes) )
673
673
}
@@ -679,7 +679,7 @@ impl RopeReader {
679
679
}
680
680
681
681
impl Iterator for RopeReader {
682
- type Item = Bytes ;
682
+ type Item = Cow < ' static , [ u8 ] > ;
683
683
684
684
fn next ( & mut self ) -> Option < Self :: Item > {
685
685
// Iterates the rope's elements recursively until we find the next Local
@@ -688,8 +688,8 @@ impl Iterator for RopeReader {
688
688
let ( inner, mut index) = match self . stack . pop ( ) {
689
689
None => return None ,
690
690
Some ( StackElem :: Local ( b) ) => {
691
- debug_assert ! ( !b. is_empty( ) , "must not have empty Bytes section" ) ;
692
- return Some ( b) ;
691
+ debug_assert ! ( !b. get_ref ( ) . is_empty( ) , "must not have empty Bytes section" ) ;
692
+ return Some ( b. into_inner ( ) ) ;
693
693
}
694
694
Some ( StackElem :: Shared ( r, i) ) => ( r, i) ,
695
695
} ;
@@ -735,17 +735,17 @@ impl BufRead for RopeReader {
735
735
// This is just so we can get a reference to the asset that is kept alive by the
736
736
// RopeReader itself. We can then auto-convert that reference into the needed u8
737
737
// slice reference.
738
- self . stack . push ( StackElem :: Local ( bytes) ) ;
738
+ self . stack . push ( StackElem :: Local ( Cursor :: new ( bytes) ) ) ;
739
739
let Some ( StackElem :: Local ( bytes) ) = self . stack . last ( ) else {
740
740
unreachable ! ( )
741
741
} ;
742
742
743
- Ok ( bytes)
743
+ Ok ( bytes. get_ref ( ) )
744
744
}
745
745
746
746
fn consume ( & mut self , amt : usize ) {
747
747
if let Some ( StackElem :: Local ( b) ) = self . stack . last_mut ( ) {
748
- if amt == b. len ( ) {
748
+ if amt == b. get_ref ( ) . len ( ) {
749
749
self . stack . pop ( ) ;
750
750
} else {
751
751
// Consume some amount of bytes from the current Bytes instance, ensuring
@@ -759,7 +759,7 @@ impl BufRead for RopeReader {
759
759
impl Stream for RopeReader {
760
760
// The Result<Bytes> item type is required for this to be streamable into a
761
761
// [Hyper::Body].
762
- type Item = Result < Bytes > ;
762
+ type Item = Result < Cow < ' static , [ u8 ] > > ;
763
763
764
764
// Returns a "result" of reading the next shared bytes reference. This
765
765
// differs from [Read::read] by not copying any memory.
@@ -772,7 +772,7 @@ impl Stream for RopeReader {
772
772
impl From < RopeElem > for StackElem {
773
773
fn from ( el : RopeElem ) -> Self {
774
774
match el {
775
- Local ( bytes) => Self :: Local ( bytes) ,
775
+ Local ( bytes) => Self :: Local ( Cursor :: new ( bytes) ) ,
776
776
Shared ( inner) => Self :: Shared ( inner, 0 ) ,
777
777
}
778
778
}
@@ -794,7 +794,7 @@ mod test {
794
794
// in order to fully test cases.
795
795
impl From < & str > for RopeElem {
796
796
fn from ( value : & str ) -> Self {
797
- RopeElem :: Local ( value. to_string ( ) . into ( ) )
797
+ RopeElem :: Local ( value. to_string ( ) . into_bytes ( ) . into ( ) )
798
798
}
799
799
}
800
800
impl From < Vec < RopeElem > > for RopeElem {
@@ -977,7 +977,10 @@ mod test {
977
977
let shared = Rope :: from ( "def" ) ;
978
978
let rope = Rope :: new ( vec ! [ "abc" . into( ) , shared. into( ) , "ghi" . into( ) ] ) ;
979
979
980
- let chunks = rope. read ( ) . collect :: < Vec < _ > > ( ) ;
980
+ let chunks = rope
981
+ . read ( )
982
+ . map ( |v| String :: from_utf8 ( v. into_owned ( ) ) . unwrap ( ) )
983
+ . collect :: < Vec < _ > > ( ) ;
981
984
982
985
assert_eq ! ( chunks, vec![ "abc" , "def" , "ghi" ] ) ;
983
986
}
0 commit comments