@@ -11,7 +11,6 @@ use crate::types::{ColNumber, LineNumber, SourceOffset};
1111use log:: debug;
1212use std:: borrow:: Cow ;
1313use std:: io:: { self , Write } ;
14- use std:: str;
1514
1615#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
1716pub enum FormattingContext {
@@ -90,7 +89,7 @@ impl<'src> ParserState<'src> {
9089 }
9190 pub ( crate ) fn push_heredoc_content < F > (
9291 & mut self ,
93- symbol : impl Into < Cow < ' src , str > > ,
92+ symbol : impl Into < Cow < ' src , [ u8 ] > > ,
9493 kind : HeredocKind ,
9594 end_line : LineNumber ,
9695 formatting_func : F ,
@@ -121,11 +120,11 @@ impl<'src> ParserState<'src> {
121120 ) ) ;
122121 }
123122
124- pub ( crate ) fn emit_heredoc_start ( & mut self , symbol : & ' src str , kind : HeredocKind ) {
123+ pub ( crate ) fn emit_heredoc_start ( & mut self , symbol : & ' src [ u8 ] , kind : HeredocKind ) {
125124 self . push_concrete_token ( ConcreteLineToken :: HeredocStart { kind, symbol } ) ;
126125 }
127126
128- pub ( crate ) fn emit_heredoc_close ( & mut self , symbol : String ) {
127+ pub ( crate ) fn emit_heredoc_close ( & mut self , symbol : Vec < u8 > ) {
129128 self . push_concrete_token ( ConcreteLineToken :: HeredocClose { symbol } ) ;
130129 }
131130
@@ -390,9 +389,9 @@ impl<'src> ParserState<'src> {
390389 self . push_concrete_token ( ConcreteLineToken :: DoubleQuote ) ;
391390 }
392391
393- pub ( crate ) fn emit_string_content ( & mut self , s : impl Into < Cow < ' src , str > > ) {
392+ pub ( crate ) fn emit_string_content ( & mut self , s : impl Into < Cow < ' src , [ u8 ] > > ) {
394393 let content = s. into ( ) ;
395- let newline_count = content. matches ( '\n' ) . count ( ) as u64 ;
394+ let newline_count = content. iter ( ) . filter ( | & & b| b == b '\n') . count ( ) as u64 ;
396395 self . current_orig_line_number += newline_count;
397396 for be in self . breakable_entry_stack . iter_mut ( ) . rev ( ) {
398397 be. push_line_number ( self . current_orig_line_number ) ;
@@ -653,7 +652,7 @@ impl<'src> ParserState<'src> {
653652 let kind = next_heredoc. kind ;
654653 let symbol = next_heredoc. closing_symbol ( ) ;
655654 let space_count = next_heredoc. indent ;
656- let string_contents = next_heredoc. render_as_string ( ) ;
655+ let string_contents = next_heredoc. render_as_bytes ( ) ;
657656
658657 // When inside a squiggly heredoc context and this is a non-squiggly heredoc,
659658 // emit RawHeredocContent tokens so the content won't receive squiggly indentation.
@@ -666,7 +665,7 @@ impl<'src> ParserState<'src> {
666665 } ) ;
667666 } else {
668667 self . push_concrete_token ( ConcreteLineToken :: DirectPart {
669- part : Cow :: Owned ( string_contents. into_bytes ( ) ) ,
668+ part : Cow :: Owned ( string_contents) ,
670669 } ) ;
671670 }
672671 self . emit_newline ( ) ;
@@ -675,14 +674,13 @@ impl<'src> ParserState<'src> {
675674 if emit_as_raw {
676675 // For bare/dash heredocs inside squiggly context, emit the close as raw content
677676 let close_content = if kind. is_bare ( ) {
678- symbol. replace ( '\'' , "" )
677+ symbol
679678 } else {
680679 // Dash heredocs can have indented close
681- format ! (
682- "{}{}" ,
683- crate :: util:: get_indent( space_count as usize ) ,
684- symbol. replace( '\'' , "" )
685- )
680+ let indent = crate :: util:: get_indent ( space_count as usize ) ;
681+ let mut content = indent. into_owned ( ) ;
682+ content. extend_from_slice ( & symbol) ;
683+ content
686684 } ;
687685 self . push_concrete_token ( ConcreteLineToken :: RawHeredocContent {
688686 content : close_content,
@@ -691,7 +689,7 @@ impl<'src> ParserState<'src> {
691689 if !kind. is_bare ( ) {
692690 self . push_concrete_token ( ConcreteLineToken :: Indent { depth : space_count } ) ;
693691 }
694- self . emit_heredoc_close ( symbol. replace ( '\'' , "" ) ) ;
692+ self . emit_heredoc_close ( symbol) ;
695693 }
696694
697695 if !skip {
@@ -820,9 +818,9 @@ impl<'src> ParserState<'src> {
820818 let final_tokens = rqw. into_tokens ( ) ;
821819
822820 let mut segments = Vec :: new ( ) ;
823- let mut current_normal = String :: new ( ) ;
821+ let mut current_normal = Vec :: new ( ) ;
824822
825- fn flush_normal ( current : & mut String , segments : & mut Vec < HeredocSegment > ) {
823+ fn flush_normal ( current : & mut Vec < u8 > , segments : & mut Vec < HeredocSegment > ) {
826824 if !current. is_empty ( ) {
827825 segments. push ( HeredocSegment :: Normal ( std:: mem:: take ( current) ) ) ;
828826 }
@@ -835,9 +833,7 @@ impl<'src> ParserState<'src> {
835833 segments. push ( HeredocSegment :: Raw ( content) ) ;
836834 } else {
837835 // Accumulate into normal content
838- current_normal
839- // TODO(@reese): Use &[u8] here when string internals are updated
840- . push_str ( std:: str:: from_utf8 ( & token. into_ruby ( ) ) . unwrap ( ) ) ;
836+ current_normal. extend_from_slice ( & token. into_ruby ( ) ) ;
841837 }
842838 }
843839
0 commit comments