]> git.lizzy.rs Git - rust.git/blobdiff - src/string.rs
Merge commit 'c4416f20dcaec5d93077f72470e83e150fb923b1' into sync-rustfmt
[rust.git] / src / string.rs
index 64ae15672df8ff1c88f3d749d6d2de14bff2f9c3..78b72a50cb2f96250ec94b1c86579d1246798424 100644 (file)
@@ -278,6 +278,9 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str]
         }
         cur_index
     };
+    if max_width_index_in_input == 0 {
+        return SnippetState::EndOfInput(input.concat());
+    }
 
     // Find the position in input for breaking the string
     if line_end.is_empty()
@@ -301,7 +304,7 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str]
         return if trim_end {
             SnippetState::LineEnd(input[..=url_index_end].concat(), index_plus_ws + 1)
         } else {
-            return SnippetState::LineEnd(input[..=index_plus_ws].concat(), index_plus_ws + 1);
+            SnippetState::LineEnd(input[..=index_plus_ws].concat(), index_plus_ws + 1)
         };
     }
 
@@ -312,20 +315,21 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str]
         // Found a whitespace and what is on its left side is big enough.
         Some(index) if index >= MIN_STRING => break_at(index),
         // No whitespace found, try looking for a punctuation instead
-        _ => match input[0..max_width_index_in_input]
-            .iter()
-            .rposition(|grapheme| is_punctuation(grapheme))
+        _ => match (0..max_width_index_in_input)
+            .rev()
+            .skip_while(|pos| !is_valid_linebreak(input, *pos))
+            .next()
         {
             // Found a punctuation and what is on its left side is big enough.
             Some(index) if index >= MIN_STRING => break_at(index),
             // Either no boundary character was found to the left of `input[max_chars]`, or the line
             // got too small. We try searching for a boundary character to the right.
-            _ => match input[max_width_index_in_input..]
-                .iter()
-                .position(|grapheme| is_whitespace(grapheme) || is_punctuation(grapheme))
+            _ => match (max_width_index_in_input..input.len())
+                .skip_while(|pos| !is_valid_linebreak(input, *pos))
+                .next()
             {
                 // A boundary was found after the line limit
-                Some(index) => break_at(max_width_index_in_input + index),
+                Some(index) => break_at(index),
                 // No boundary to the right, the input cannot be broken
                 None => SnippetState::EndOfInput(input.concat()),
             },
@@ -333,6 +337,23 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str]
     }
 }
 
+fn is_valid_linebreak(input: &[&str], pos: usize) -> bool {
+    let is_whitespace = is_whitespace(input[pos]);
+    if is_whitespace {
+        return true;
+    }
+    let is_punctuation = is_punctuation(input[pos]);
+    if is_punctuation && !is_part_of_type(input, pos) {
+        return true;
+    }
+    false
+}
+
+fn is_part_of_type(input: &[&str], pos: usize) -> bool {
+    input.get(pos..=pos + 1) == Some(&[":", ":"])
+        || input.get(pos.saturating_sub(1)..=pos) == Some(&[":", ":"])
+}
+
 fn is_new_line(grapheme: &str) -> bool {
     let bytes = grapheme.as_bytes();
     bytes.starts_with(b"\n") || bytes.starts_with(b"\r\n")
@@ -366,6 +387,19 @@ fn issue343() {
         rewrite_string("eq_", &fmt, 2);
     }
 
+    #[test]
+    fn line_break_at_valid_points_test() {
+        let string = "[TheName](Dont::break::my::type::That::would::be::very::nice) break here";
+        let graphemes = UnicodeSegmentation::graphemes(&*string, false).collect::<Vec<&str>>();
+        assert_eq!(
+            break_string(20, false, "", &graphemes[..]),
+            SnippetState::LineEnd(
+                "[TheName](Dont::break::my::type::That::would::be::very::nice) ".to_string(),
+                62
+            )
+        );
+    }
+
     #[test]
     fn should_break_on_whitespace() {
         let string = "Placerat felis. Mauris porta ante sagittis purus.";