@@ -421,6 +421,8 @@ impl CodeBlockAttribute {
421421/// An item starts with either a star `*` or a dash `-`. Different level of indentation are
422422/// handled by shrinking the shape accordingly.
423423struct ItemizedBlock {
424+ /// the lines that are identified as part of an itemized block
425+ lines : Vec < String > ,
424426 /// the number of whitespaces up to the item sigil
425427 indent : usize ,
426428 /// the string that marks the start of an item
@@ -442,6 +444,7 @@ impl ItemizedBlock {
442444 let space_to_sigil = line. chars ( ) . take_while ( |c| c. is_whitespace ( ) ) . count ( ) ;
443445 let indent = space_to_sigil + 2 ;
444446 ItemizedBlock {
447+ lines : vec ! [ line[ indent..] . to_string( ) ] ,
445448 indent,
446449 opener : line[ ..indent] . to_string ( ) ,
447450 line_start : " " . repeat ( indent) ,
@@ -461,10 +464,29 @@ impl ItemizedBlock {
461464 }
462465 }
463466
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)
467471 && 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 " )
468490 }
469491}
470492
@@ -473,7 +495,6 @@ struct CommentRewrite<'a> {
473495 code_block_buffer : String ,
474496 is_prev_line_multi_line : bool ,
475497 code_block_attr : Option < CodeBlockAttribute > ,
476- item_block_buffer : String ,
477498 item_block : Option < ItemizedBlock > ,
478499 comment_line_separator : String ,
479500 indent_str : String ,
@@ -511,7 +532,6 @@ impl<'a> CommentRewrite<'a> {
511532 code_block_buffer : String :: with_capacity ( 128 ) ,
512533 is_prev_line_multi_line : false ,
513534 code_block_attr : None ,
514- item_block_buffer : String :: with_capacity ( 128 ) ,
515535 item_block : None ,
516536 comment_line_separator : format ! ( "{}{}" , indent_str, line_start) ,
517537 max_chars,
@@ -561,17 +581,14 @@ impl<'a> CommentRewrite<'a> {
561581 ) ) ;
562582 }
563583
564- if ! self . item_block_buffer . is_empty ( ) {
584+ if let Some ( ref ib ) = self . item_block {
565585 // the last few lines are part of an itemized block
566586 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 ( ) ;
570587 let item_fmt = ib. create_string_format ( & self . fmt ) ;
571588 self . result . push_str ( & self . comment_line_separator ) ;
572589 self . result . push_str ( & ib. opener ) ;
573590 match rewrite_string (
574- & self . item_block_buffer . replace ( " \n " , " " ) ,
591+ & ib . trimmed_block_as_string ( ) ,
575592 & item_fmt,
576593 self . max_chars . saturating_sub ( ib. indent ) ,
577594 ) {
@@ -580,7 +597,7 @@ impl<'a> CommentRewrite<'a> {
580597 & format ! ( "{}{}" , & self . comment_line_separator, ib. line_start) ,
581598 ) ) ,
582599 None => self . result . push_str ( & Self :: join_block (
583- & self . item_block_buffer ,
600+ & ib . original_block_as_string ( ) ,
584601 & self . comment_line_separator ,
585602 ) ) ,
586603 } ;
@@ -604,10 +621,8 @@ impl<'a> CommentRewrite<'a> {
604621 ) -> bool {
605622 let is_last = i == count_newlines ( orig) ;
606623
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) {
611626 return false ;
612627 }
613628 self . is_prev_line_multi_line = false ;
@@ -616,7 +631,7 @@ impl<'a> CommentRewrite<'a> {
616631 self . result . push_str ( & self . comment_line_separator ) ;
617632 self . result . push_str ( & ib. opener ) ;
618633 match rewrite_string (
619- & self . item_block_buffer . replace ( " \n " , " " ) ,
634+ & ib . trimmed_block_as_string ( ) ,
620635 & item_fmt,
621636 self . max_chars . saturating_sub ( ib. indent ) ,
622637 ) {
@@ -625,11 +640,10 @@ impl<'a> CommentRewrite<'a> {
625640 & format ! ( "{}{}" , & self . comment_line_separator, ib. line_start) ,
626641 ) ) ,
627642 None => self . result . push_str ( & Self :: join_block (
628- & self . item_block_buffer ,
643+ & ib . original_block_as_string ( ) ,
629644 & self . comment_line_separator ,
630645 ) ) ,
631646 } ;
632- self . item_block_buffer . clear ( ) ;
633647 } else if self . code_block_attr . is_some ( ) {
634648 if line. starts_with ( "```" ) {
635649 let code_block = match self . code_block_attr . as_ref ( ) . unwrap ( ) {
@@ -669,8 +683,6 @@ impl<'a> CommentRewrite<'a> {
669683 self . code_block_attr = Some ( CodeBlockAttribute :: new ( & line[ 3 ..] ) )
670684 } else if self . fmt . config . wrap_comments ( ) && ItemizedBlock :: is_itemized_line ( & line) {
671685 let ib = ItemizedBlock :: new ( & line) ;
672- self . item_block_buffer . push_str ( & line[ ib. indent ..] ) ;
673- self . item_block_buffer . push ( '\n' ) ;
674686 self . item_block = Some ( ib) ;
675687 return false ;
676688 }
0 commit comments