chiark / gitweb /
Tidy up: make Option and Vec pass through TextFragment.
authorSimon Tatham <anakin@pobox.com>
Thu, 4 Jan 2024 07:26:14 +0000 (07:26 +0000)
committerSimon Tatham <anakin@pobox.com>
Thu, 4 Jan 2024 08:14:00 +0000 (08:14 +0000)
Now if you have an Option<TextFragment>, or a Vec<TextFragment> (or
even, heaven help you, an Option<Vec> or a Vec<Option<Vec>> etc), you
can just call .render() on the whole thing without having to manually
loop over it. I'm starting to like this feature of Rust!

src/text.rs

index 7f1250baab86e812c095a61a3b5e7655a6c0698c..527003d0656de49f5394ac8765484e799c2b7dc3 100644 (file)
@@ -19,6 +19,21 @@ pub trait TextFragment {
     fn render(&self, width: usize) -> Vec<ColouredString>;
 }
 
+impl<T: TextFragment> TextFragment for Option<T> {
+    fn render(&self, width: usize) -> Vec<ColouredString> {
+        match self {
+            Some(ref inner) => inner.render(width),
+            None => Vec::new(),
+        }
+    }
+}
+
+impl<T: TextFragment> TextFragment for Vec<T> {
+    fn render(&self, width: usize) -> Vec<ColouredString> {
+        itertools::concat(self.iter().map(|x| x.render(width)))
+    }
+}
+
 pub struct BlankLine {}
 
 impl BlankLine {
@@ -1463,12 +1478,8 @@ impl TextFragment for StatusDisplay {
 
         push_fragment(&mut lines, self.sep.render(width));
         push_fragment(&mut lines, self.from.render(width));
-        if let Some(via) = &self.via {
-            push_fragment(&mut lines, via.render(width));
-        }
-        if let Some(irt) = &self.irt {
-            push_fragment(&mut lines,irt.render(width));
-        }
+        push_fragment(&mut lines, self.via.render(width));
+        push_fragment(&mut lines, self.irt.render(width));
         push_fragment(&mut lines, self.blank.render(width));
         let rendered_content = self.content.render(width);
         let content_empty = rendered_content.len() == 0;
@@ -1500,6 +1511,7 @@ pub struct DetailedStatusDisplay {
     replies: Paragraph,
     boosts: Paragraph,
     favourites: Paragraph,
+    mentions_header: Option<Paragraph>,
     mentions: Vec<Paragraph>,
     client_name: Paragraph,
     client_url: Paragraph,
@@ -1578,14 +1590,16 @@ impl DetailedStatusDisplay {
             .add(&ColouredString::plain(
                 &format!("Favourites: {}", st.favourites_count)));
 
-        let mut mentions: Vec<_> = st.mentions.iter().map(|m| {
+        let mentions: Vec<_> = st.mentions.iter().map(|m| {
             Paragraph::new().set_indent(2, 2)
                 .add(&ColouredString::uniform(&client.fq(&m.acct), 'f'))
         }).collect();
-        if !mentions.is_empty() {
-            mentions.insert(0, Paragraph::new().add(
-                &ColouredString::plain("Mentioned users:")));
-        }
+        let mentions_header = if mentions.is_empty() {
+            None
+        } else {
+            Some(Paragraph::new().add(
+                &ColouredString::plain("Mentioned users:")))
+        };
 
         let client_name = Paragraph::new()
             .add(&ColouredString::plain("Client name: "))
@@ -1616,6 +1630,7 @@ impl DetailedStatusDisplay {
             boosts,
             favourites,
             mentions,
+            mentions_header,
             client_name,
             client_url,
             sep: SeparatorLine::new(None, false, false),
@@ -1633,9 +1648,7 @@ impl TextFragment for DetailedStatusDisplay {
         push_fragment(&mut lines, self.blank.render(width));
 
         push_fragment(&mut lines, self.id.render(width));
-        if let Some(webstatus) = &self.webstatus {
-            push_fragment(&mut lines, webstatus.render(width));
-        }
+        push_fragment(&mut lines, self.webstatus.render(width));
         push_fragment(&mut lines, self.blank.render(width));
 
         push_fragment(&mut lines, self.creation.render(width));
@@ -1656,9 +1669,8 @@ impl TextFragment for DetailedStatusDisplay {
         push_fragment(&mut lines, self.blank.render(width));
 
         if !self.mentions.is_empty() {
-            for para in &self.mentions {
-                push_fragment(&mut lines, para.render(width));
-            }
+            push_fragment(&mut lines, self.mentions_header.render(width));
+            push_fragment(&mut lines, self.mentions.render(width));
             push_fragment(&mut lines, self.blank.render(width));
         }
 
@@ -1900,16 +1912,12 @@ impl TextFragment for ExamineUserDisplay {
         }
 
         if !self.flags.is_empty() {
-            for para in &self.flags {
-                push_fragment(&mut lines, para.render(width));
-            }
+            push_fragment(&mut lines, self.flags.render(width));
             push_fragment(&mut lines, self.blank.render(width));
         }
 
         if !self.relationships.is_empty() {
-            for para in &self.relationships {
-                push_fragment(&mut lines, para.render(width));
-            }
+            push_fragment(&mut lines, self.relationships.render(width));
             push_fragment(&mut lines, self.blank.render(width));
         }