@@ -3,12 +3,14 @@ use crate::delimiters::BreakableDelims;
33use crate :: file_comments:: FileComments ;
44use crate :: heredoc_string:: { HeredocKind , HeredocSegment , HeredocString } ;
55use crate :: line_tokens:: * ;
6- use crate :: render_queue_writer:: { MAX_LINE_LENGTH , RenderQueueWriter } ;
7- use crate :: render_targets:: { BaseQueue , Breakable , BreakableCallChainEntry , BreakableEntry } ;
6+ use crate :: render_queue_writer:: RenderQueueWriter ;
7+ use crate :: render_targets:: {
8+ BaseQueue , Breakable , BreakableCallChainEntry , BreakableEntry , ConditionalLayoutEntry ,
9+ } ;
810use crate :: types:: { ColNumber , LineNumber , SourceOffset } ;
911use log:: debug;
1012use std:: borrow:: Cow ;
11- use std:: io:: { self , Cursor , Write } ;
13+ use std:: io:: { self , Write } ;
1214use std:: str;
1315
1416#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
@@ -176,19 +178,6 @@ impl<'src> ParserState<'src> {
176178 }
177179 }
178180
179- pub ( crate ) fn will_render_as_multiline < F > ( & mut self , f : F ) -> bool
180- where
181- F : FnOnce ( & mut ParserState < ' src > ) ,
182- {
183- let mut next_ps = ParserState :: new_with_indent_from ( self ) ;
184- // Ignore commments when determining line length
185- next_ps. with_suppress_comments ( true , f) ;
186- let data = next_ps. render_to_buffer ( ) ;
187-
188- let s = str:: from_utf8 ( & data) . expect ( "string is utf8" ) ;
189- s. trim ( ) . contains ( '\n' ) || s. len ( ) > MAX_LINE_LENGTH
190- }
191-
192181 pub ( crate ) fn has_comment_in_offset_span (
193182 & self ,
194183 start_offset : SourceOffset ,
@@ -322,15 +311,6 @@ impl<'src> ParserState<'src> {
322311 ) ) ;
323312 }
324313
325- pub ( crate ) fn with_suppress_comments < F > ( & mut self , suppress : bool , f : F )
326- where
327- F : FnOnce ( & mut ParserState < ' src > ) ,
328- {
329- self . suppress_comments_stack . push ( suppress) ;
330- f ( self ) ;
331- self . suppress_comments_stack . pop ( ) ;
332- }
333-
334314 pub ( crate ) fn new_block < F > ( & mut self , f : F )
335315 where
336316 F : FnOnce ( & mut ParserState < ' src > ) ,
@@ -828,12 +808,6 @@ impl<'src> ParserState<'src> {
828808 }
829809 }
830810
831- pub ( crate ) fn new_with_indent_from ( ps : & ParserState < ' src > ) -> Self {
832- let mut next_ps = ParserState :: new_with_reset_indentation ( ps) ;
833- next_ps. indent_depth = ps. indent_depth ;
834- next_ps
835- }
836-
837811 // Creates a copy of the parser state *with the indent_depth reset*.
838812 // This is used for heredocs, where we explicitly want to ignore current indentation.
839813 pub ( crate ) fn new_with_reset_indentation ( ps : & ParserState < ' src > ) -> Self {
@@ -844,13 +818,6 @@ impl<'src> ParserState<'src> {
844818 next_ps
845819 }
846820
847- pub ( crate ) fn render_to_buffer ( self ) -> Vec < u8 > {
848- let mut bufio = Cursor :: new ( Vec :: new ( ) ) ;
849- self . write ( & mut bufio) . expect ( "in memory io cannot fail" ) ;
850- bufio. set_position ( 0 ) ;
851- bufio. into_inner ( )
852- }
853-
854821 /// Convert the render queue to heredoc segments. This separates content into
855822 /// Normal segments (which should receive squiggly indentation) and Raw segments
856823 /// (content from nested non-squiggly heredocs that should not be indented).
@@ -968,6 +935,51 @@ impl<'src> ParserState<'src> {
968935 None => self . render_queue . push ( Self :: dangerously_convert ( t) ) ,
969936 }
970937 }
938+
939+ /// Format a conditional modifier expression (e.g., `x if y` or `x unless y`).
940+ pub ( crate ) fn conditional_layout_of < FP , FS > (
941+ & mut self ,
942+ keyword : & ' static str ,
943+ format_predicate : FP ,
944+ format_statement : FS ,
945+ ) where
946+ FP : FnOnce ( & mut ParserState < ' src > ) ,
947+ FS : FnOnce ( & mut ParserState < ' src > ) ,
948+ {
949+ // Save and clear any pending comments to prevent them from being
950+ // inserted into the conditional layout
951+ let saved_comments = self . comments_to_insert . take ( ) ;
952+
953+ let entry = ConditionalLayoutEntry :: new ( keyword, self . current_spaces ( ) ) ;
954+ self . breakable_entry_stack
955+ . push ( Breakable :: InlineConditional ( entry) ) ;
956+
957+ self . with_start_of_line ( false , |ps| {
958+ ps. new_block ( format_predicate) ;
959+ } ) ;
960+
961+ self . breakable_entry_stack
962+ . last_mut ( )
963+ . expect ( "just pushed InlineConditional" )
964+ . as_conditional_layout_mut ( )
965+ . expect ( "just pushed InlineConditional" )
966+ . switch_to_statement ( ) ;
967+
968+ self . with_start_of_line ( false , |ps| {
969+ ps. new_block ( format_statement) ;
970+ } ) ;
971+
972+ let cle = self
973+ . breakable_entry_stack
974+ . pop ( )
975+ . expect ( "just pushed InlineConditional" )
976+ . into_conditional_layout ( )
977+ . expect ( "InlineConditional always returns Some from into_conditional_layout" ) ;
978+
979+ self . comments_to_insert = saved_comments;
980+
981+ self . push_target ( ConcreteLineTokenAndTargets :: ConditionalLayoutEntry ( cle) ) ;
982+ }
971983}
972984
973985pub fn line_difference_requires_newline ( to_line : LineNumber , from_line : LineNumber ) -> bool {
0 commit comments