@@ -161,23 +161,24 @@ impl ReplaceSource {
161161
162162impl Source for ReplaceSource {
163163 fn source ( & self ) -> SourceValue {
164- let rope = self . rope ( ) ;
165- if rope . len ( ) == 1 {
166- SourceValue :: String ( Cow :: Borrowed ( rope [ 0 ] ) )
164+ let ( chunks , len ) = self . rope ( ) ;
165+ if chunks . len ( ) == 1 {
166+ SourceValue :: String ( Cow :: Borrowed ( chunks [ 0 ] ) )
167167 } else {
168- let mut string = String :: with_capacity ( rope . iter ( ) . map ( |c| c . len ( ) ) . sum ( ) ) ;
169- for chunk in rope {
168+ let mut string = String :: with_capacity ( len) ;
169+ for chunk in chunks {
170170 string. push_str ( chunk) ;
171171 }
172172 SourceValue :: String ( Cow :: Owned ( string) )
173173 }
174174 }
175175
176176 #[ allow( unsafe_code) ]
177- fn rope ( & self ) -> Vec < & str > {
178- let inner_rope = self . inner . rope ( ) ;
179- let mut rope: Vec < & str > =
180- Vec :: with_capacity ( inner_rope. len ( ) + self . replacements . len ( ) * 2 ) ;
177+ fn rope ( & self ) -> ( Vec < & str > , usize ) {
178+ let ( inner_chunks, _) = self . inner . rope ( ) ;
179+ let mut chunks: Vec < & str > =
180+ Vec :: with_capacity ( inner_chunks. len ( ) + self . replacements . len ( ) * 2 ) ;
181+ let mut len: usize = 0 ;
181182
182183 let mut pos: usize = 0 ;
183184 let mut replacement_idx: usize = 0 ;
@@ -186,7 +187,7 @@ impl Source for ReplaceSource {
186187 < self . replacements . len ( ) )
187188 . then ( || self . replacements [ replacement_idx] . start as usize ) ;
188189
189- ' chunk_loop: for chunk in inner_rope {
190+ ' chunk_loop: for chunk in inner_chunks {
190191 let mut chunk_pos = 0 ;
191192 let end_pos = pos + chunk. len ( ) ;
192193
@@ -213,14 +214,16 @@ impl Source for ReplaceSource {
213214 let offset = next_replacement_pos - pos;
214215 let chunk_slice =
215216 unsafe { & chunk. get_unchecked ( chunk_pos..( chunk_pos + offset) ) } ;
216- rope. push ( chunk_slice) ;
217+ chunks. push ( chunk_slice) ;
218+ len += chunk_slice. len ( ) ;
217219 chunk_pos += offset;
218220 pos = next_replacement_pos;
219221 }
220222 // Insert replacement content split into chunks by lines
221223 let replacement =
222224 unsafe { & self . replacements . get_unchecked ( replacement_idx) } ;
223- rope. push ( & replacement. content ) ;
225+ chunks. push ( & replacement. content ) ;
226+ len += replacement. content . len ( ) ;
224227
225228 // Remove replaced content by settings this variable
226229 replacement_end = if let Some ( replacement_end) = replacement_end {
@@ -260,7 +263,9 @@ impl Source for ReplaceSource {
260263
261264 // Emit remaining chunk
262265 if chunk_pos < chunk. len ( ) {
263- rope. push ( unsafe { & chunk. get_unchecked ( chunk_pos..) } ) ;
266+ let chunk = unsafe { & chunk. get_unchecked ( chunk_pos..) } ;
267+ chunks. push ( chunk) ;
268+ len += chunk. len ( ) ;
264269 }
265270 pos = end_pos;
266271 }
@@ -269,11 +274,12 @@ impl Source for ReplaceSource {
269274 while replacement_idx < self . replacements . len ( ) {
270275 let content =
271276 unsafe { & self . replacements . get_unchecked ( replacement_idx) . content } ;
272- rope. push ( content) ;
277+ chunks. push ( content) ;
278+ len += content. len ( ) ;
273279 replacement_idx += 1 ;
274280 }
275281
276- rope
282+ ( chunks , len )
277283 }
278284
279285 fn buffer ( & self ) -> Cow < [ u8 ] > {
@@ -334,13 +340,13 @@ impl Source for ReplaceSource {
334340 }
335341
336342 fn write_to_string ( & self , string : & mut String ) {
337- for chunk in self . rope ( ) {
343+ for chunk in self . rope ( ) . 0 {
338344 string. push_str ( chunk) ;
339345 }
340346 }
341347
342348 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
343- for text in self . rope ( ) {
349+ for text in self . rope ( ) . 0 {
344350 writer. write_all ( text. as_bytes ( ) ) ?;
345351 }
346352 Ok ( ( ) )
0 commit comments