@@ -421,6 +421,8 @@ impl CodeBlockAttribute {
421
421
/// An item starts with either a star `*` or a dash `-`. Different level of indentation are
422
422
/// handled by shrinking the shape accordingly.
423
423
struct ItemizedBlock {
424
+ /// the lines that are identified as part of an itemized block
425
+ lines : Vec < String > ,
424
426
/// the number of whitespaces up to the item sigil
425
427
indent : usize ,
426
428
/// the string that marks the start of an item
@@ -442,6 +444,7 @@ impl ItemizedBlock {
442
444
let space_to_sigil = line. chars ( ) . take_while ( |c| c. is_whitespace ( ) ) . count ( ) ;
443
445
let indent = space_to_sigil + 2 ;
444
446
ItemizedBlock {
447
+ lines : vec ! [ line[ indent..] . to_string( ) ] ,
445
448
indent,
446
449
opener : line[ ..indent] . to_string ( ) ,
447
450
line_start : " " . repeat ( indent) ,
@@ -461,10 +464,29 @@ impl ItemizedBlock {
461
464
}
462
465
}
463
466
464
- /// Returns true if the line is part of the current itemized block
465
- fn in_block ( & self , line : & str ) -> bool {
466
- !ItemizedBlock :: is_itemized_line ( line)
467
+ /// Returns true if the line is part of the current itemized block.
468
+ /// If it is, then it is added to the internal lines vec.
469
+ fn add_line ( & mut self , line : & str ) -> bool {
470
+ if !ItemizedBlock :: is_itemized_line ( line)
467
471
&& self . indent <= line. chars ( ) . take_while ( |c| c. is_whitespace ( ) ) . count ( )
472
+ {
473
+ self . lines . push ( line. to_string ( ) ) ;
474
+ return true ;
475
+ }
476
+ false
477
+ }
478
+
479
+ /// Returns the block as a string, with each line trimmed at the start.
480
+ fn trimmed_block_as_string ( & self ) -> String {
481
+ self . lines
482
+ . iter ( )
483
+ . map ( |line| format ! ( "{} " , line. trim_start( ) ) )
484
+ . collect :: < String > ( )
485
+ }
486
+
487
+ /// Returns the block as a string under its original form
488
+ fn original_block_as_string ( & self ) -> String {
489
+ self . lines . join ( "\n " )
468
490
}
469
491
}
470
492
@@ -473,7 +495,6 @@ struct CommentRewrite<'a> {
473
495
code_block_buffer : String ,
474
496
is_prev_line_multi_line : bool ,
475
497
code_block_attr : Option < CodeBlockAttribute > ,
476
- item_block_buffer : String ,
477
498
item_block : Option < ItemizedBlock > ,
478
499
comment_line_separator : String ,
479
500
indent_str : String ,
@@ -511,7 +532,6 @@ impl<'a> CommentRewrite<'a> {
511
532
code_block_buffer : String :: with_capacity ( 128 ) ,
512
533
is_prev_line_multi_line : false ,
513
534
code_block_attr : None ,
514
- item_block_buffer : String :: with_capacity ( 128 ) ,
515
535
item_block : None ,
516
536
comment_line_separator : format ! ( "{}{}" , indent_str, line_start) ,
517
537
max_chars,
@@ -561,17 +581,14 @@ impl<'a> CommentRewrite<'a> {
561
581
) ) ;
562
582
}
563
583
564
- if ! self . item_block_buffer . is_empty ( ) {
584
+ if let Some ( ref ib ) = self . item_block {
565
585
// the last few lines are part of an itemized block
566
586
self . fmt . shape = Shape :: legacy ( self . max_chars , self . fmt_indent ) ;
567
- let mut ib = None ;
568
- :: std:: mem:: swap ( & mut ib, & mut self . item_block ) ;
569
- let ib = ib. unwrap ( ) ;
570
587
let item_fmt = ib. create_string_format ( & self . fmt ) ;
571
588
self . result . push_str ( & self . comment_line_separator ) ;
572
589
self . result . push_str ( & ib. opener ) ;
573
590
match rewrite_string (
574
- & self . item_block_buffer . replace ( " \n " , " " ) ,
591
+ & ib . trimmed_block_as_string ( ) ,
575
592
& item_fmt,
576
593
self . max_chars . saturating_sub ( ib. indent ) ,
577
594
) {
@@ -580,7 +597,7 @@ impl<'a> CommentRewrite<'a> {
580
597
& format ! ( "{}{}" , & self . comment_line_separator, ib. line_start) ,
581
598
) ) ,
582
599
None => self . result . push_str ( & Self :: join_block (
583
- & self . item_block_buffer ,
600
+ & ib . original_block_as_string ( ) ,
584
601
& self . comment_line_separator ,
585
602
) ) ,
586
603
} ;
@@ -604,10 +621,8 @@ impl<'a> CommentRewrite<'a> {
604
621
) -> bool {
605
622
let is_last = i == count_newlines ( orig) ;
606
623
607
- if let Some ( ref ib) = self . item_block {
608
- if ib. in_block ( & line) {
609
- self . item_block_buffer . push_str ( line. trim_start ( ) ) ;
610
- self . item_block_buffer . push ( '\n' ) ;
624
+ if let Some ( ref mut ib) = self . item_block {
625
+ if ib. add_line ( & line) {
611
626
return false ;
612
627
}
613
628
self . is_prev_line_multi_line = false ;
@@ -616,7 +631,7 @@ impl<'a> CommentRewrite<'a> {
616
631
self . result . push_str ( & self . comment_line_separator ) ;
617
632
self . result . push_str ( & ib. opener ) ;
618
633
match rewrite_string (
619
- & self . item_block_buffer . replace ( " \n " , " " ) ,
634
+ & ib . trimmed_block_as_string ( ) ,
620
635
& item_fmt,
621
636
self . max_chars . saturating_sub ( ib. indent ) ,
622
637
) {
@@ -625,11 +640,10 @@ impl<'a> CommentRewrite<'a> {
625
640
& format ! ( "{}{}" , & self . comment_line_separator, ib. line_start) ,
626
641
) ) ,
627
642
None => self . result . push_str ( & Self :: join_block (
628
- & self . item_block_buffer ,
643
+ & ib . original_block_as_string ( ) ,
629
644
& self . comment_line_separator ,
630
645
) ) ,
631
646
} ;
632
- self . item_block_buffer . clear ( ) ;
633
647
} else if self . code_block_attr . is_some ( ) {
634
648
if line. starts_with ( "```" ) {
635
649
let code_block = match self . code_block_attr . as_ref ( ) . unwrap ( ) {
@@ -669,8 +683,6 @@ impl<'a> CommentRewrite<'a> {
669
683
self . code_block_attr = Some ( CodeBlockAttribute :: new ( & line[ 3 ..] ) )
670
684
} else if self . fmt . config . wrap_comments ( ) && ItemizedBlock :: is_itemized_line ( & line) {
671
685
let ib = ItemizedBlock :: new ( & line) ;
672
- self . item_block_buffer . push_str ( & line[ ib. indent ..] ) ;
673
- self . item_block_buffer . push ( '\n' ) ;
674
686
self . item_block = Some ( ib) ;
675
687
return false ;
676
688
}
0 commit comments