@@ -389,12 +389,17 @@ impl Comments {
389389
390390 /// Collapse this collection of comments and separate each comment with `\n` as a single [`Comment`].
391391 #[ must_use]
392- pub fn collapse_comments ( self ) -> Option < Comment > {
392+ pub fn collapse_comments ( self , flatten : MultiFlatten ) -> Option < Comment > {
393393 let mut iter = self . comments . into_iter ( ) ;
394394 let first = iter. next ( ) ?;
395395
396396 let Some ( second) = iter. next ( ) else {
397- return Some ( first) ;
397+ let text = first. text ( ) ;
398+ return Some ( Comment :: new (
399+ flatten_lines ( text, flatten) ,
400+ first. kind ( ) . to_owned ( ) ,
401+ first. span ( ) . to_owned ( ) ,
402+ ) ) ;
398403 } ;
399404
400405 let start = * first. span ( ) . start ( ) ;
@@ -411,8 +416,28 @@ impl Comments {
411416 end = * c. span ( ) . end ( ) ;
412417 }
413418
414- Some ( Comment :: new ( text, CommentKind :: MultiLine , Span :: new ( start, end) ) )
419+ Some ( Comment :: new (
420+ flatten_lines ( & text, flatten) ,
421+ CommentKind :: MultiLine ,
422+ Span :: new ( start, end) ,
423+ ) )
424+ }
425+ }
426+
427+ fn flatten_lines ( lines : & str , flatten : MultiFlatten ) -> String {
428+ let mut out = String :: new ( ) ;
429+ let sep = match flatten {
430+ MultiFlatten :: FlattenWithNone => String :: new ( ) ,
431+ MultiFlatten :: NoFlat => return lines. to_owned ( ) ,
432+ MultiFlatten :: Flatten ( chars) => chars. to_owned ( ) ,
433+ } ;
434+ for ( i, line) in lines. lines ( ) . enumerate ( ) {
435+ if i > 0 {
436+ out. push_str ( & sep) ;
437+ }
438+ out. push_str ( line) ;
415439 }
440+ out
416441}
417442
418443/// Controls how leading comments are captured for a statement.
@@ -427,6 +452,18 @@ pub enum LeadingCommentCapture {
427452 AllSingleOneMulti ,
428453}
429454
455+ /// Enum for multiline comment flattening.
456+ #[ derive( Clone , Copy , Debug , Default , Eq , PartialEq ) ]
457+ pub enum MultiFlatten < ' a > {
458+ /// Default option, retains multiline structure with `\n`
459+ #[ default]
460+ NoFlat ,
461+ /// Sets multiline comments to be flattened and combined without adding formatting
462+ FlattenWithNone ,
463+ /// Will flatten comments and amend the content of [`String`] to the end of the former leading lines
464+ Flatten ( & ' a str ) ,
465+ }
466+
430467#[ cfg( test) ]
431468mod tests {
432469 use std:: { env, fs} ;
@@ -937,7 +974,7 @@ CREATE TABLE t (id INTEGER);
937974 #[ test]
938975 fn collapse_comments_empty_returns_none ( ) {
939976 let comments = Comments :: new ( vec ! [ ] ) ;
940- assert ! ( comments. collapse_comments( ) . is_none( ) ) ;
977+ assert ! ( comments. collapse_comments( crate :: comments :: MultiFlatten :: NoFlat ) . is_none( ) ) ;
941978 }
942979
943980 #[ test]
@@ -949,8 +986,9 @@ CREATE TABLE t (id INTEGER);
949986 ) ;
950987 let comments = Comments :: new ( vec ! [ c] ) ;
951988
952- let collapsed =
953- comments. collapse_comments ( ) . unwrap_or_else ( || panic ! ( "should return a comment" ) ) ;
989+ let collapsed = comments
990+ . collapse_comments ( crate :: comments:: MultiFlatten :: NoFlat )
991+ . unwrap_or_else ( || panic ! ( "should return a comment" ) ) ;
954992 assert_eq ! ( collapsed. text( ) , "solo" ) ;
955993 assert_eq ! ( collapsed. kind( ) , & CommentKind :: SingleLine ) ;
956994 assert_eq ! ( collapsed. span( ) , & Span :: new( Location :: new( 10 , 3 ) , Location :: new( 10 , 11 ) ) ) ;
@@ -976,7 +1014,9 @@ CREATE TABLE t (id INTEGER);
9761014
9771015 let comments = Comments :: new ( vec ! [ c1, c2, c3] ) ;
9781016
979- let collapsed = comments. collapse_comments ( ) . unwrap_or_else ( || panic ! ( "should collapse" ) ) ;
1017+ let collapsed = comments
1018+ . collapse_comments ( crate :: comments:: MultiFlatten :: NoFlat )
1019+ . unwrap_or_else ( || panic ! ( "should collapse" ) ) ;
9801020 assert_eq ! ( collapsed. text( ) , "a\n b\n c" ) ;
9811021 assert_eq ! ( collapsed. kind( ) , & CommentKind :: MultiLine ) ;
9821022 assert_eq ! ( collapsed. span( ) , & Span :: new( Location :: new( 1 , 1 ) , Location :: new( 4 , 3 ) ) ) ;
@@ -995,7 +1035,9 @@ CREATE TABLE t (id INTEGER);
9951035 let leading = parsed. leading_comments ( 3 , LeadingCommentCapture :: AllLeading ) ;
9961036 assert_eq ! ( texts( & leading) , vec![ "c1" . to_owned( ) , "c2" . to_owned( ) ] ) ;
9971037
998- let collapsed = leading. collapse_comments ( ) . unwrap_or_else ( || panic ! ( "should collapse" ) ) ;
1038+ let collapsed = leading
1039+ . collapse_comments ( crate :: comments:: MultiFlatten :: NoFlat )
1040+ . unwrap_or_else ( || panic ! ( "should collapse" ) ) ;
9991041 assert_eq ! ( collapsed. text( ) , "c1\n c2" ) ;
10001042 assert_eq ! ( collapsed. kind( ) , & CommentKind :: MultiLine ) ;
10011043
@@ -1018,10 +1060,23 @@ CREATE TABLE t (id INTEGER);
10181060 let leading = parsed. leading_comments ( 3 , LeadingCommentCapture :: SingleNearest ) ;
10191061 assert_eq ! ( texts( & leading) , vec![ "c2" . to_owned( ) ] ) ;
10201062
1021- let collapsed = leading. collapse_comments ( ) . unwrap_or_else ( || panic ! ( "should collapse" ) ) ;
1063+ let collapsed = leading
1064+ . collapse_comments ( crate :: comments:: MultiFlatten :: NoFlat )
1065+ . unwrap_or_else ( || panic ! ( "should collapse" ) ) ;
10221066 assert_eq ! ( collapsed. text( ) , "c2" ) ;
10231067 assert_eq ! ( collapsed. kind( ) , & CommentKind :: SingleLine ) ;
10241068
10251069 Ok ( ( ) )
10261070 }
1071+ use crate :: comments:: flatten_lines;
1072+ #[ test]
1073+ fn test_flatten_lines_behavior ( ) {
1074+ let input = "a\n b\n c" ;
1075+ let no_sep = flatten_lines ( input, crate :: comments:: MultiFlatten :: FlattenWithNone ) ;
1076+ assert_eq ! ( no_sep, "abc" ) ;
1077+ let dash_sep = flatten_lines ( input, crate :: comments:: MultiFlatten :: Flatten ( " - " ) ) ;
1078+ assert_eq ! ( dash_sep, "a - b - c" ) ;
1079+ let single = flatten_lines ( "solo" , crate :: comments:: MultiFlatten :: Flatten ( "XXX" ) ) ;
1080+ assert_eq ! ( single, "solo" ) ;
1081+ }
10271082}
0 commit comments