chiark / gitweb /
Factor out truncation of a ColouredString
authorSimon Tatham <anakin@pobox.com>
Sun, 24 Dec 2023 22:29:48 +0000 (22:29 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 24 Dec 2023 22:29:48 +0000 (22:29 +0000)
src/coloured_string.rs
src/text.rs

index b9a62940969fc1b1d774cb27b5b3b6fa15bca6ee..080679984b3231c32b5699d3642b1f890701a5a5 100644 (file)
@@ -53,6 +53,10 @@ impl ColouredString {
             colour: &self.colour,
         }
     }
+
+    pub fn truncate(&self, width: usize) -> ColouredStringSlice {
+        self.split(width).next().unwrap()
+    }
 }
 
 impl<'a> ColouredStringSlice<'a> {
@@ -75,6 +79,10 @@ impl<'a> ColouredStringSlice<'a> {
     pub fn nchars(&self) -> usize { self.text.chars().count() }
     pub fn width(&self) -> usize { UnicodeWidthStr::width(&self.text as &str) }
     pub fn text(&self) -> &'a str { &self.text }
+
+    pub fn truncate(&'a self, width: usize) -> ColouredStringSlice<'a> {
+        self.split(width).next().unwrap()
+    }
 }
 
 impl std::ops::Add<ColouredString> for ColouredString {
@@ -138,6 +146,7 @@ pub struct ColouredStringSplitIterator<'a> {
     width: usize,
     textpos: usize,
     colourpos: usize,
+    delivered_empty: bool,
 }
 
 impl<'a> ColouredStringSlice<'a> {
@@ -154,6 +163,7 @@ impl<'a> ColouredStringSlice<'a> {
             width: width,
             textpos: 0,
             colourpos: 0,
+            delivered_empty: false,
         }
     }
 }
@@ -172,6 +182,7 @@ impl<'a> ColouredString {
             width: width,
             textpos: 0,
             colourpos: 0,
+            delivered_empty: false,
         }
     }
 }
@@ -222,7 +233,14 @@ impl<'a> Iterator for ColouredStringSplitIterator<'a> {
         let colourslice = &self.cs.colour[self.colourpos..];
         let mut colourit = colourslice.char_indices();
         match (textit.next(), colourit.next()) {
-            (None, None) => None,
+            (None, None) => {
+                if self.textpos == 0 && !self.delivered_empty {
+                    self.delivered_empty = true;
+                    Some(ColouredStringSlice::general("", ""))
+                } else {
+                    None
+                }
+            },
             (Some((_, tc)), Some(_)) => {
                 let mut tpos: usize = 0;
                 let mut cpos: usize = 0;
@@ -322,4 +340,9 @@ fn test_split() {
     assert_eq!(lines.next(), Some(ColouredStringSlice::general("efg", "qrs")));
     assert_eq!(lines.next(), Some(ColouredStringSlice::general("h", "t")));
     assert_eq!(lines.next(), None);
+
+    let cs = ColouredStringSlice::general("", "");
+    let mut lines = cs.split(3);
+    assert_eq!(lines.next(), Some(ColouredStringSlice::general("", "")));
+    assert_eq!(lines.next(), None);
 }
index 43f66f208a0487001f309ff26e0dc88b408d50ca..05f471149d4026edf42e49b56a5b0dddcd063e99 100644 (file)
@@ -72,7 +72,7 @@ impl TextFragment for SeparatorLine {
                 suffix;
         }
         vec! {
-            suffix.split(width).next().unwrap().to_owned()
+            suffix.truncate(width).to_owned()
         }
     }
 }
@@ -89,7 +89,7 @@ impl TextFragment for EditorHeaderSeparator {
             ColouredString::uniform(
                 &((&"-".repeat(max(0, width - 2))).to_string() + "|"),
                 '-',
-            ).split(width).next().unwrap().to_owned(),
+            ).truncate(width).to_owned(),
         }
     }
 }