@@ -206,8 +206,10 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Source for ReplaceSource<T> {
206206 }
207207
208208 fn buffer ( & self ) -> Cow < [ u8 ] > {
209- let source = self . source ( ) . to_string ( ) ;
210- Cow :: Owned ( source. into_bytes ( ) )
209+ match self . source ( ) {
210+ Cow :: Borrowed ( s) => Cow :: Borrowed ( s. as_bytes ( ) ) ,
211+ Cow :: Owned ( s) => Cow :: Owned ( s. into_bytes ( ) ) ,
212+ }
211213 }
212214
213215 fn size ( & self ) -> usize {
@@ -407,10 +409,17 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
407409 if next_replacement_pos > pos {
408410 // Emit chunk until replacement
409411 let offset = next_replacement_pos - pos;
410- let chunk_slice =
411- & chunk[ chunk_pos as usize ..( chunk_pos + offset) as usize ] ;
412+ let chunk_slice = match & chunk {
413+ Cow :: Borrowed ( c) => Cow :: Borrowed (
414+ & c[ chunk_pos as usize ..( chunk_pos + offset) as usize ] ,
415+ ) ,
416+ Cow :: Owned ( c) => Cow :: Owned (
417+ c[ chunk_pos as usize ..( chunk_pos + offset) as usize ]
418+ . to_string ( ) ,
419+ ) ,
420+ } ;
412421 on_chunk (
413- Some ( Cow :: Owned ( chunk_slice. to_string ( ) ) ) ,
422+ Some ( chunk_slice. clone ( ) ) ,
414423 Mapping {
415424 generated_line : line as u32 ,
416425 generated_column : ( ( mapping. generated_column as i64 )
@@ -440,16 +449,20 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
440449 original. source_index ,
441450 original. original_line ,
442451 original. original_column ,
443- chunk_slice,
452+ & chunk_slice,
444453 )
445454 } )
446455 {
447456 original. original_column += chunk_slice. len ( ) as u32 ;
448457 }
449458 }
450459 // Insert replacement content split into chunks by lines
460+ #[ allow( unsafe_code) ]
461+ // SAFETY: The safety of this operation relies on the fact that the `ReplaceSource` type will not delete the `replacements` during its entire lifetime.
462+ let repl = unsafe {
463+ std:: mem:: transmute :: < & Replacement , & ' a Replacement > ( & repls[ i] )
464+ } ;
451465
452- let repl = & repls[ i] ;
453466 let lines: Vec < & str > = split_into_lines ( & repl. content ) . collect ( ) ;
454467 let mut replacement_name_index = mapping
455468 . original
@@ -463,14 +476,14 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
463476 if global_index. is_none ( ) {
464477 let len = name_mapping. len ( ) as u32 ;
465478 name_mapping. insert ( Cow :: Borrowed ( name) , len) ;
466- on_name. borrow_mut ( ) ( len, Cow :: Owned ( name. to_string ( ) ) ) ;
479+ on_name. borrow_mut ( ) ( len, Cow :: Borrowed ( name) ) ;
467480 global_index = Some ( len) ;
468481 }
469482 replacement_name_index = global_index;
470483 }
471484 for ( m, content_line) in lines. iter ( ) . enumerate ( ) {
472485 on_chunk (
473- Some ( Cow :: Owned ( content_line. to_string ( ) ) ) ,
486+ Some ( Cow :: Borrowed ( content_line) ) ,
474487 Mapping {
475488 generated_line : line as u32 ,
476489 generated_column : ( ( mapping. generated_column as i64 )
@@ -581,7 +594,10 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
581594 let chunk_slice = if chunk_pos == 0 {
582595 chunk
583596 } else {
584- Cow :: Owned ( chunk[ chunk_pos as usize ..] . to_string ( ) )
597+ match chunk {
598+ Cow :: Borrowed ( c) => Cow :: Borrowed ( & c[ chunk_pos as usize ..] ) ,
599+ Cow :: Owned ( c) => Cow :: Owned ( c[ chunk_pos as usize ..] . to_string ( ) ) ,
600+ }
585601 } ;
586602 let line = mapping. generated_line as i64 + generated_line_offset;
587603 on_chunk (
0 commit comments