File tree Expand file tree Collapse file tree 8 files changed +54
-2
lines changed Expand file tree Collapse file tree 8 files changed +54
-2
lines changed Original file line number Diff line number Diff line change @@ -128,6 +128,10 @@ impl Source for CachedSource {
128128 }
129129 }
130130
131+ fn write_to_string ( & self , string : & mut String ) {
132+ self . inner . write_to_string ( string) ;
133+ }
134+
131135 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
132136 self . inner . to_writer ( writer)
133137 }
Original file line number Diff line number Diff line change @@ -167,7 +167,11 @@ impl Source for ConcatSource {
167167 if children. len ( ) == 1 {
168168 children[ 0 ] . source ( )
169169 } else {
170- SourceValue :: String ( Cow :: Owned ( self . rope ( ) . join ( "" ) ) )
170+ // Use to_writer to avoid multiple heap allocations that would occur
171+ // when concatenating nested ConcatSource instances directly
172+ let mut string = String :: with_capacity ( self . size ( ) ) ;
173+ self . write_to_string ( & mut string) ;
174+ SourceValue :: String ( Cow :: Owned ( string) )
171175 }
172176 }
173177
@@ -214,6 +218,12 @@ impl Source for ConcatSource {
214218 result
215219 }
216220
221+ fn write_to_string ( & self , string : & mut String ) {
222+ for child in self . optimized_children ( ) {
223+ child. write_to_string ( string) ;
224+ }
225+ }
226+
217227 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
218228 for child in self . optimized_children ( ) {
219229 child. to_writer ( writer) ?;
Original file line number Diff line number Diff line change @@ -77,6 +77,10 @@ impl Source for OriginalSource {
7777 get_map ( object_pool, chunks. as_ref ( ) , options)
7878 }
7979
80+ fn write_to_string ( & self , string : & mut String ) {
81+ string. push_str ( self . value . as_ref ( ) ) ;
82+ }
83+
8084 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
8185 writer. write_all ( self . value . as_bytes ( ) )
8286 }
Original file line number Diff line number Diff line change @@ -80,6 +80,10 @@ impl Source for RawStringSource {
8080 None
8181 }
8282
83+ fn write_to_string ( & self , string : & mut String ) {
84+ string. push_str ( self . 0 . as_ref ( ) ) ;
85+ }
86+
8387 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
8488 writer. write_all ( self . 0 . as_bytes ( ) )
8589 }
@@ -226,6 +230,10 @@ impl Source for RawBufferSource {
226230 None
227231 }
228232
233+ fn write_to_string ( & self , string : & mut String ) {
234+ string. push_str ( self . get_or_init_value_as_string ( ) ) ;
235+ }
236+
229237 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
230238 writer. write_all ( & self . value )
231239 }
Original file line number Diff line number Diff line change @@ -181,7 +181,7 @@ impl Source for ReplaceSource {
181181 < self . replacements . len ( ) )
182182 . then ( || self . replacements [ replacement_idx] . start as usize ) ;
183183
184- ' chunk_loop: for chunk in self . inner . rope ( ) {
184+ ' chunk_loop: for chunk in inner_rope {
185185 let mut chunk_pos = 0 ;
186186 let end_pos = pos + chunk. len ( ) ;
187187
@@ -323,6 +323,12 @@ impl Source for ReplaceSource {
323323 get_map ( & ObjectPool :: default ( ) , chunks. as_ref ( ) , options)
324324 }
325325
326+ fn write_to_string ( & self , string : & mut String ) {
327+ for chunk in self . rope ( ) {
328+ string. push_str ( chunk) ;
329+ }
330+ }
331+
326332 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
327333 for text in self . rope ( ) {
328334 writer. write_all ( text. as_bytes ( ) ) ?;
Original file line number Diff line number Diff line change @@ -135,6 +135,14 @@ pub trait Source:
135135 self . dyn_hash ( state) ;
136136 }
137137
138+ /// Appends the source content to the provided string buffer.
139+ ///
140+ /// This method efficiently writes the source content directly into an existing
141+ /// string buffer, avoiding additional memory allocations when the buffer has
142+ /// sufficient capacity. This is particularly useful for concatenating multiple
143+ /// sources or building larger strings incrementally.
144+ fn write_to_string ( & self , string : & mut String ) ;
145+
138146 /// Writes the source into a writer, preferably a `std::io::BufWriter<std::io::Write>`.
139147 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > ;
140148}
@@ -164,6 +172,10 @@ impl Source for BoxSource {
164172 self . as_ref ( ) . map ( object_pool, options)
165173 }
166174
175+ fn write_to_string ( & self , string : & mut String ) {
176+ self . as_ref ( ) . write_to_string ( string)
177+ }
178+
167179 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
168180 self . as_ref ( ) . to_writer ( writer)
169181 }
Original file line number Diff line number Diff line change @@ -118,6 +118,10 @@ impl Source for SourceMapSource {
118118 get_map ( object_pool, chunks. as_ref ( ) , options)
119119 }
120120
121+ fn write_to_string ( & self , string : & mut String ) {
122+ string. push_str ( self . value . as_ref ( ) ) ;
123+ }
124+
121125 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
122126 writer. write_all ( self . value . as_bytes ( ) )
123127 }
Original file line number Diff line number Diff line change @@ -39,6 +39,10 @@ impl Source for CompatSource {
3939 self . 1 . clone ( )
4040 }
4141
42+ fn write_to_string ( & self , string : & mut String ) {
43+ string. push_str ( self . 0 . as_ref ( ) )
44+ }
45+
4246 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
4347 writer. write_all ( self . 0 . as_bytes ( ) )
4448 }
You can’t perform that action at this time.
0 commit comments