@@ -315,27 +315,45 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str]
315315 // Found a whitespace and what is on its left side is big enough.
316316 Some ( index) if index >= MIN_STRING => break_at ( index) ,
317317 // 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 ( )
321322 {
322323 // Found a punctuation and what is on its left side is big enough.
323324 Some ( index) if index >= MIN_STRING => break_at ( index) ,
324325 // Either no boundary character was found to the left of `input[max_chars]`, or the line
325326 // 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 ( )
329330 {
330331 // 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) ,
332333 // No boundary to the right, the input cannot be broken
333334 None => SnippetState :: EndOfInput ( input. concat ( ) ) ,
334335 } ,
335336 } ,
336337 }
337338}
338339
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+
339357fn is_new_line ( grapheme : & str ) -> bool {
340358 let bytes = grapheme. as_bytes ( ) ;
341359 bytes. starts_with ( b"\n " ) || bytes. starts_with ( b"\r \n " )
@@ -369,6 +387,19 @@ mod test {
369387 rewrite_string ( "eq_" , & fmt, 2 ) ;
370388 }
371389
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+
372403 #[ test]
373404 fn should_break_on_whitespace ( ) {
374405 let string = "Placerat felis. Mauris porta ante sagittis purus." ;
0 commit comments