@@ -118,7 +118,12 @@ pub fn rewrite_string<'a>(orig: &str, fmt: &StringFormat<'a>) -> Option<String>
118
118
}
119
119
120
120
// The input starting at cur_start needs to be broken
121
- match break_string ( cur_max_chars, fmt. trim_end , & graphemes[ cur_start..] ) {
121
+ match break_string (
122
+ cur_max_chars,
123
+ fmt. trim_end ,
124
+ fmt. line_end ,
125
+ & graphemes[ cur_start..] ,
126
+ ) {
122
127
SnippetState :: LineEnd ( line, len) => {
123
128
result. push_str ( & line) ;
124
129
result. push_str ( fmt. line_end ) ;
@@ -190,7 +195,7 @@ enum SnippetState {
190
195
191
196
/// Break the input string at a boundary character around the offset `max_chars`. A boundary
192
197
/// character is either a punctuation or a whitespace.
193
- fn break_string ( max_chars : usize , trim_end : bool , input : & [ & str ] ) -> SnippetState {
198
+ fn break_string ( max_chars : usize , trim_end : bool , line_end : & str , input : & [ & str ] ) -> SnippetState {
194
199
let break_at = |index /* grapheme at index is included */ | {
195
200
// Take in any whitespaces to the left/right of `input[index]` while
196
201
// preserving line feeds
@@ -242,6 +247,17 @@ fn break_string(max_chars: usize, trim_end: bool, input: &[&str]) -> SnippetStat
242
247
} ;
243
248
244
249
// Find the position in input for breaking the string
250
+ if line_end. is_empty ( )
251
+ && trim_end
252
+ && !is_whitespace ( input[ max_chars - 1 ] )
253
+ && is_whitespace ( input[ max_chars] )
254
+ {
255
+ // At a breaking point already
256
+ // The line won't invalidate the rewriting because:
257
+ // - no extra space needed for the line_end character
258
+ // - extra whitespaces to the right can be trimmed
259
+ return break_at ( max_chars - 1 ) ;
260
+ }
245
261
match input[ 0 ..max_chars]
246
262
. iter ( )
247
263
. rposition ( |grapheme| is_whitespace ( grapheme) )
@@ -304,11 +320,11 @@ mod test {
304
320
let string = "Placerat felis. Mauris porta ante sagittis purus." ;
305
321
let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
306
322
assert_eq ! (
307
- break_string( 20 , false , & graphemes[ ..] ) ,
323
+ break_string( 20 , false , "" , & graphemes[ ..] ) ,
308
324
SnippetState :: LineEnd ( "Placerat felis. " . to_string( ) , 16 )
309
325
) ;
310
326
assert_eq ! (
311
- break_string( 20 , true , & graphemes[ ..] ) ,
327
+ break_string( 20 , true , "" , & graphemes[ ..] ) ,
312
328
SnippetState :: LineEnd ( "Placerat felis." . to_string( ) , 16 )
313
329
) ;
314
330
}
@@ -318,7 +334,7 @@ mod test {
318
334
let string = "Placerat_felis._Mauris_porta_ante_sagittis_purus." ;
319
335
let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
320
336
assert_eq ! (
321
- break_string( 20 , false , & graphemes[ ..] ) ,
337
+ break_string( 20 , false , "" , & graphemes[ ..] ) ,
322
338
SnippetState :: LineEnd ( "Placerat_felis." . to_string( ) , 15 )
323
339
) ;
324
340
}
@@ -328,11 +344,11 @@ mod test {
328
344
let string = "Venenatis_tellus_vel_tellus. Aliquam aliquam dolor at justo." ;
329
345
let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
330
346
assert_eq ! (
331
- break_string( 20 , false , & graphemes[ ..] ) ,
347
+ break_string( 20 , false , "" , & graphemes[ ..] ) ,
332
348
SnippetState :: LineEnd ( "Venenatis_tellus_vel_tellus. " . to_string( ) , 29 )
333
349
) ;
334
350
assert_eq ! (
335
- break_string( 20 , true , & graphemes[ ..] ) ,
351
+ break_string( 20 , true , "" , & graphemes[ ..] ) ,
336
352
SnippetState :: LineEnd ( "Venenatis_tellus_vel_tellus." . to_string( ) , 29 )
337
353
) ;
338
354
}
@@ -342,7 +358,7 @@ mod test {
342
358
let string = "Venenatis_tellus_vel_tellus" ;
343
359
let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
344
360
assert_eq ! (
345
- break_string( 20 , false , & graphemes[ ..] ) ,
361
+ break_string( 20 , false , "" , & graphemes[ ..] ) ,
346
362
SnippetState :: EndOfInput ( "Venenatis_tellus_vel_tellus" . to_string( ) )
347
363
) ;
348
364
}
@@ -352,21 +368,21 @@ mod test {
352
368
let string = "Neque in sem. \n Pellentesque tellus augue." ;
353
369
let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
354
370
assert_eq ! (
355
- break_string( 15 , false , & graphemes[ ..] ) ,
371
+ break_string( 15 , false , "" , & graphemes[ ..] ) ,
356
372
SnippetState :: EndWithLineFeed ( "Neque in sem. \n " . to_string( ) , 20 )
357
373
) ;
358
374
assert_eq ! (
359
- break_string( 25 , false , & graphemes[ ..] ) ,
375
+ break_string( 25 , false , "" , & graphemes[ ..] ) ,
360
376
SnippetState :: EndWithLineFeed ( "Neque in sem. \n " . to_string( ) , 20 )
361
377
) ;
362
- // if `StringFormat::line_end` is true, then the line feed does not matter anymore
378
+
363
379
assert_eq ! (
364
- break_string( 15 , true , & graphemes[ ..] ) ,
365
- SnippetState :: LineEnd ( "Neque in sem." . to_string( ) , 26 )
380
+ break_string( 15 , true , "" , & graphemes[ ..] ) ,
381
+ SnippetState :: LineEnd ( "Neque in sem." . to_string( ) , 19 )
366
382
) ;
367
383
assert_eq ! (
368
- break_string( 25 , true , & graphemes[ ..] ) ,
369
- SnippetState :: LineEnd ( "Neque in sem." . to_string( ) , 26 )
384
+ break_string( 25 , true , "" , & graphemes[ ..] ) ,
385
+ SnippetState :: EndWithLineFeed ( "Neque in sem.\n " . to_string( ) , 20 )
370
386
) ;
371
387
}
372
388
@@ -375,11 +391,11 @@ mod test {
375
391
let string = "Neque in sem. Pellentesque tellus augue." ;
376
392
let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
377
393
assert_eq ! (
378
- break_string( 20 , false , & graphemes[ ..] ) ,
394
+ break_string( 20 , false , "" , & graphemes[ ..] ) ,
379
395
SnippetState :: LineEnd ( "Neque in sem. " . to_string( ) , 25 )
380
396
) ;
381
397
assert_eq ! (
382
- break_string( 20 , true , & graphemes[ ..] ) ,
398
+ break_string( 20 , true , "" , & graphemes[ ..] ) ,
383
399
SnippetState :: LineEnd ( "Neque in sem." . to_string( ) , 25 )
384
400
) ;
385
401
}
@@ -390,11 +406,11 @@ mod test {
390
406
391
407
let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
392
408
assert_eq ! (
393
- break_string( 25 , false , & graphemes[ ..] ) ,
409
+ break_string( 25 , false , "" , & graphemes[ ..] ) ,
394
410
SnippetState :: EndWithLineFeed ( "Nulla\n " . to_string( ) , 6 )
395
411
) ;
396
412
assert_eq ! (
397
- break_string( 25 , true , & graphemes[ ..] ) ,
413
+ break_string( 25 , true , "" , & graphemes[ ..] ) ,
398
414
SnippetState :: EndWithLineFeed ( "Nulla\n " . to_string( ) , 6 )
399
415
) ;
400
416
@@ -559,4 +575,39 @@ mod test {
559
575
Some ( "Aenean\n //\n // metus. Vestibulum ac\n // lacus." . to_string( ) )
560
576
) ;
561
577
}
578
+
579
+ #[ test]
580
+ fn boundary_on_edge ( ) {
581
+ let config: Config = Default :: default ( ) ;
582
+ let mut fmt = StringFormat {
583
+ opener : "" ,
584
+ closer : "" ,
585
+ line_start : "// " ,
586
+ line_end : "" ,
587
+ shape : Shape :: legacy ( 13 , Indent :: from_width ( & config, 4 ) ) ,
588
+ trim_end : true ,
589
+ config : & config,
590
+ } ;
591
+
592
+ let comment = "Aenean metus. Vestibulum ac lacus." ;
593
+ assert_eq ! (
594
+ rewrite_string( comment, & fmt) ,
595
+ Some ( "Aenean metus.\n // Vestibulum ac\n // lacus." . to_string( ) )
596
+ ) ;
597
+
598
+ fmt. trim_end = false ;
599
+ let comment = "Vestibulum ac lacus." ;
600
+ assert_eq ! (
601
+ rewrite_string( comment, & fmt) ,
602
+ Some ( "Vestibulum \n // ac lacus." . to_string( ) )
603
+ ) ;
604
+
605
+ fmt. trim_end = true ;
606
+ fmt. line_end = "\\ " ;
607
+ let comment = "Vestibulum ac lacus." ;
608
+ assert_eq ! (
609
+ rewrite_string( comment, & fmt) ,
610
+ Some ( "Vestibulum\\ \n // ac lacus." . to_string( ) )
611
+ ) ;
612
+ }
562
613
}
0 commit comments