@@ -416,6 +416,8 @@ impl CodeBlockAttribute {
416
416
/// An item starts with either a star `*` or a dash `-`. Different level of indentation are
417
417
/// handled by shrinking the shape accordingly.
418
418
struct ItemizedBlock {
419
+ /// the lines that are identified as part of an itemized block
420
+ lines : Vec < String > ,
419
421
/// the number of whitespaces up to the item sigil
420
422
indent : usize ,
421
423
/// the string that marks the start of an item
@@ -437,6 +439,7 @@ impl ItemizedBlock {
437
439
let space_to_sigil = line. chars ( ) . take_while ( |c| c. is_whitespace ( ) ) . count ( ) ;
438
440
let indent = space_to_sigil + 2 ;
439
441
ItemizedBlock {
442
+ lines : vec ! [ line[ indent..] . to_string( ) ] ,
440
443
indent,
441
444
opener : line[ ..indent] . to_string ( ) ,
442
445
line_start : " " . repeat ( indent) ,
@@ -456,10 +459,32 @@ impl ItemizedBlock {
456
459
}
457
460
}
458
461
459
- /// Returns true if the line is part of the current itemized block
460
- fn in_block ( & self , line : & str ) -> bool {
461
- !ItemizedBlock :: is_itemized_line ( line)
462
+ /// Returns true if the line is part of the current itemized block.
463
+ /// If it is, then it is added to the internal lines vec.
464
+ fn add_line ( & mut self , line : & str ) -> bool {
465
+ if !ItemizedBlock :: is_itemized_line ( line)
462
466
&& self . indent <= line. chars ( ) . take_while ( |c| c. is_whitespace ( ) ) . count ( )
467
+ {
468
+ self . lines . push ( line. to_string ( ) ) ;
469
+ return true ;
470
+ }
471
+ false
472
+ }
473
+
474
+ /// Returns the block as a string, with each line trimmed at the start.
475
+ fn trimmed_block_as_string ( & self ) -> String {
476
+ self . lines
477
+ . iter ( )
478
+ . map ( |line| format ! ( "{} " , line. trim_start( ) ) )
479
+ . collect :: < String > ( )
480
+ }
481
+
482
+ /// Returns the block as a string under its original form
483
+ fn original_block_as_string ( & self ) -> String {
484
+ self . lines
485
+ . iter ( )
486
+ . map ( |line| format ! ( "{}\n " , line) )
487
+ . collect :: < String > ( )
463
488
}
464
489
}
465
490
@@ -468,7 +493,6 @@ struct CommentRewrite<'a> {
468
493
code_block_buffer : String ,
469
494
is_prev_line_multi_line : bool ,
470
495
code_block_attr : Option < CodeBlockAttribute > ,
471
- item_block_buffer : String ,
472
496
item_block : Option < ItemizedBlock > ,
473
497
comment_line_separator : String ,
474
498
indent_str : String ,
@@ -506,7 +530,6 @@ impl<'a> CommentRewrite<'a> {
506
530
code_block_buffer : String :: with_capacity ( 128 ) ,
507
531
is_prev_line_multi_line : false ,
508
532
code_block_attr : None ,
509
- item_block_buffer : String :: with_capacity ( 128 ) ,
510
533
item_block : None ,
511
534
comment_line_separator : format ! ( "{}{}" , indent_str, line_start) ,
512
535
max_chars,
@@ -556,17 +579,14 @@ impl<'a> CommentRewrite<'a> {
556
579
) ) ;
557
580
}
558
581
559
- if ! self . item_block_buffer . is_empty ( ) {
582
+ if let Some ( ref ib ) = self . item_block {
560
583
// the last few lines are part of an itemized block
561
584
self . fmt . shape = Shape :: legacy ( self . max_chars , self . fmt_indent ) ;
562
- let mut ib = None ;
563
- :: std:: mem:: swap ( & mut ib, & mut self . item_block ) ;
564
- let ib = ib. unwrap ( ) ;
565
585
let item_fmt = ib. create_string_format ( & self . fmt ) ;
566
586
self . result . push_str ( & self . comment_line_separator ) ;
567
587
self . result . push_str ( & ib. opener ) ;
568
588
match rewrite_string (
569
- & self . item_block_buffer . replace ( " \n " , " " ) ,
589
+ & ib . trimmed_block_as_string ( ) ,
570
590
& item_fmt,
571
591
self . max_chars . saturating_sub ( ib. indent ) ,
572
592
) {
@@ -575,7 +595,7 @@ impl<'a> CommentRewrite<'a> {
575
595
& format ! ( "{}{}" , & self . comment_line_separator, ib. line_start) ,
576
596
) ) ,
577
597
None => self . result . push_str ( & Self :: join_block (
578
- & self . item_block_buffer ,
598
+ & ib . original_block_as_string ( ) ,
579
599
& self . comment_line_separator ,
580
600
) ) ,
581
601
} ;
@@ -599,10 +619,8 @@ impl<'a> CommentRewrite<'a> {
599
619
) -> bool {
600
620
let is_last = i == count_newlines ( orig) ;
601
621
602
- if let Some ( ref ib) = self . item_block {
603
- if ib. in_block ( & line) {
604
- self . item_block_buffer . push_str ( line. trim_start ( ) ) ;
605
- self . item_block_buffer . push ( '\n' ) ;
622
+ if let Some ( ref mut ib) = self . item_block {
623
+ if ib. add_line ( & line) {
606
624
return false ;
607
625
}
608
626
self . is_prev_line_multi_line = false ;
@@ -611,7 +629,7 @@ impl<'a> CommentRewrite<'a> {
611
629
self . result . push_str ( & self . comment_line_separator ) ;
612
630
self . result . push_str ( & ib. opener ) ;
613
631
match rewrite_string (
614
- & self . item_block_buffer . replace ( " \n " , " " ) ,
632
+ & ib . trimmed_block_as_string ( ) ,
615
633
& item_fmt,
616
634
self . max_chars . saturating_sub ( ib. indent ) ,
617
635
) {
@@ -620,11 +638,10 @@ impl<'a> CommentRewrite<'a> {
620
638
& format ! ( "{}{}" , & self . comment_line_separator, ib. line_start) ,
621
639
) ) ,
622
640
None => self . result . push_str ( & Self :: join_block (
623
- & self . item_block_buffer ,
641
+ & ib . original_block_as_string ( ) ,
624
642
& self . comment_line_separator ,
625
643
) ) ,
626
644
} ;
627
- self . item_block_buffer . clear ( ) ;
628
645
} else if self . code_block_attr . is_some ( ) {
629
646
if line. starts_with ( "```" ) {
630
647
let code_block = match self . code_block_attr . as_ref ( ) . unwrap ( ) {
@@ -664,8 +681,6 @@ impl<'a> CommentRewrite<'a> {
664
681
self . code_block_attr = Some ( CodeBlockAttribute :: new ( & line[ 3 ..] ) )
665
682
} else if self . fmt . config . wrap_comments ( ) && ItemizedBlock :: is_itemized_line ( & line) {
666
683
let ib = ItemizedBlock :: new ( & line) ;
667
- self . item_block_buffer . push_str ( & line[ ib. indent ..] ) ;
668
- self . item_block_buffer . push ( '\n' ) ;
669
684
self . item_block = Some ( ib) ;
670
685
return false ;
671
686
}
0 commit comments