@@ -315,27 +315,45 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str]
315
315
// Found a whitespace and what is on its left side is big enough.
316
316
Some ( index) if index >= MIN_STRING => break_at ( index) ,
317
317
// No whitespace found, try looking for a punctuation instead
318
- _ => match input[ 0 ..max_width_index_in_input]
319
- . iter ( )
320
- . rposition ( |grapheme| is_punctuation ( grapheme) )
318
+ _ => match ( 0 ..max_width_index_in_input)
319
+ . rev ( )
320
+ . skip_while ( |pos| !is_valid_linebreak ( input, * pos) )
321
+ . next ( )
321
322
{
322
323
// Found a punctuation and what is on its left side is big enough.
323
324
Some ( index) if index >= MIN_STRING => break_at ( index) ,
324
325
// Either no boundary character was found to the left of `input[max_chars]`, or the line
325
326
// got too small. We try searching for a boundary character to the right.
326
- _ => match input [ max_width_index_in_input..]
327
- . iter ( )
328
- . position ( |grapheme| is_whitespace ( grapheme ) || is_punctuation ( grapheme ) )
327
+ _ => match ( max_width_index_in_input..input . len ( ) )
328
+ . skip_while ( |pos| ! is_valid_linebreak ( input , * pos ) )
329
+ . next ( )
329
330
{
330
331
// A boundary was found after the line limit
331
- Some ( index) => break_at ( max_width_index_in_input + index) ,
332
+ Some ( index) => break_at ( index) ,
332
333
// No boundary to the right, the input cannot be broken
333
334
None => SnippetState :: EndOfInput ( input. concat ( ) ) ,
334
335
} ,
335
336
} ,
336
337
}
337
338
}
338
339
340
+ fn is_valid_linebreak ( input : & [ & str ] , pos : usize ) -> bool {
341
+ let is_whitespace = is_whitespace ( input[ pos] ) ;
342
+ if is_whitespace {
343
+ return true ;
344
+ }
345
+ let is_punctuation = is_punctuation ( input[ pos] ) ;
346
+ if is_punctuation && !is_part_of_type ( input, pos) {
347
+ return true ;
348
+ }
349
+ false
350
+ }
351
+
352
+ fn is_part_of_type ( input : & [ & str ] , pos : usize ) -> bool {
353
+ input. get ( pos..=pos + 1 ) == Some ( & [ ":" , ":" ] )
354
+ || input. get ( pos. saturating_sub ( 1 ) ..=pos) == Some ( & [ ":" , ":" ] )
355
+ }
356
+
339
357
fn is_new_line ( grapheme : & str ) -> bool {
340
358
let bytes = grapheme. as_bytes ( ) ;
341
359
bytes. starts_with ( b"\n " ) || bytes. starts_with ( b"\r \n " )
@@ -369,6 +387,19 @@ mod test {
369
387
rewrite_string ( "eq_" , & fmt, 2 ) ;
370
388
}
371
389
390
+ #[ test]
391
+ fn line_break_at_valid_points_test ( ) {
392
+ let string = "[TheName](Dont::break::my::type::That::would::be::very::nice) break here" ;
393
+ let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
394
+ assert_eq ! (
395
+ break_string( 20 , false , "" , & graphemes[ ..] ) ,
396
+ SnippetState :: LineEnd (
397
+ "[TheName](Dont::break::my::type::That::would::be::very::nice) " . to_string( ) ,
398
+ 62
399
+ )
400
+ ) ;
401
+ }
402
+
372
403
#[ test]
373
404
fn should_break_on_whitespace ( ) {
374
405
let string = "Placerat felis. Mauris porta ante sagittis purus." ;
0 commit comments