chiark / gitweb /
Apply many uncontroversial style fixes from Clippy.
authorSimon Tatham <anakin@pobox.com>
Sat, 6 Jan 2024 00:23:00 +0000 (00:23 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 6 Jan 2024 09:28:09 +0000 (09:28 +0000)
I ran 'cargo clippy fix', picked out the changes I didn't disagree
with, and reformatted a few overlong lines that resulted. It's a
combination of redundant clones and borrows, what Clippy considers to
be the antipattern of assert_eq!(boolean, true), and failure to use
the full vocabulary of standard methods like Option::is_none,
Result::is_ok, and the various and_then() or map() etc combinators.

12 files changed:
src/activity_stack.rs
src/client.rs
src/coloured_string.rs
src/editor.rs
src/file.rs
src/html.rs
src/login.rs
src/main.rs
src/posting.rs
src/scan_re.rs
src/text.rs
src/tui.rs

index 917ce6b88ec5610641b8476e7fb1af7c638a2ca6..42a013509903300f796b63f1dd27bb2b342e8540 100644 (file)
@@ -153,14 +153,11 @@ impl ActivityStack {
     }
 
     pub fn overlay(&self) -> Option<Activity> {
-        match &self.overlay {
-            Some(x) => Some(Activity::Overlay(x.clone())),
-            _ => None,
-        }
+        self.overlay.as_ref().map(|x| Activity::Overlay(x.clone()))
     }
 
     pub fn chain_to(&mut self, act: Activity) {
-        assert!(!self.overlay.is_some(),
+        assert!(self.overlay.is_none(),
                 "Don't expect to chain overlay actions");
         self.pop();
         self.goto(act);
index a223af856ab713726c011cfd58ffc398aae156b0..b93ad451ead573547b3f5ef333b716f97428ebcf 100644 (file)
@@ -419,12 +419,12 @@ impl Client {
         let (url, rsp) = self.api_request(Req::get("v2/instance"))?;
         let rspstatus = rsp.status();
         let inst: Instance = if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             match serde_json::from_str(&rsp.text()?) {
                 Ok(ac) => Ok(ac),
                 Err(e) => Err(ClientError::UrlError(
-                    url.clone(), e.to_string())),
+                    url, e.to_string())),
             }
         }?;
         self.instance = Some(inst.clone());
@@ -446,7 +446,7 @@ impl Client {
     fn cache_notification(&mut self, n: &Notification) {
         self.cache_account(&n.account);
         if let Some(st) = &n.status {
-            self.cache_status(&st);
+            self.cache_status(st);
         }
         self.notifications.insert(n.id.to_string(), n.clone());
     }
@@ -470,7 +470,7 @@ impl Client {
         }?;
         if ac.id != id {
             return Err(ClientError::UrlError(
-                url.clone(), format!("request returned wrong account id {}",
+                url, format!("request returned wrong account id {}",
                                      &ac.id)));
         }
         self.cache_account(&ac);
@@ -498,7 +498,7 @@ impl Client {
             }
         }
         Err(ClientError::UrlError(
-            url.clone(), format!(
+            url, format!(
                 "request did not return expected account id {}", id)))
     }
 
@@ -528,7 +528,7 @@ impl Client {
         }?;
         if st.id != id {
             return Err(ClientError::UrlError(
-                url.clone(), format!("request returned wrong status id {}",
+                url, format!("request returned wrong status id {}",
                                      &st.id)));
         }
         self.cache_status(&st);
@@ -545,10 +545,7 @@ impl Client {
                 // we had cached
                 not.account = ac.clone();
             }
-            let status_id = match not.status {
-                Some(ref st) => Some(&st.id),
-                None => None,
-            };
+            let status_id = not.status.as_ref().map(|st| &st.id);
             if let Some(status_id) = status_id {
                 if let Some(st) = self.statuses.get(status_id) {
                     not.status = Some(st.clone());
@@ -572,7 +569,7 @@ impl Client {
         }?;
         if not.id != id {
             return Err(ClientError::UrlError(
-                url.clone(), format!(
+                url, format!(
                     "request returned wrong notification id {}", &not.id)));
         }
         self.cache_notification(&not);
@@ -596,16 +593,14 @@ impl Client {
                 // below where we did end up retrieving something.
                 return Ok(false);
             }
-        } else {
-            if !self.feeds.contains_key(id) {
-                // We might be called on to extend a feed that we've
-                // not yet fetched for the first time, if a streaming
-                // notification comes in before the user has yet taken
-                // us into the activity reading that feed. If so,
-                // ignore the event; the _actual_ initial fetch will
-                // deal with it later.
-                return Ok(false);
-            }
+        } else if !self.feeds.contains_key(id) {
+            // We might be called on to extend a feed that we've
+            // not yet fetched for the first time, if a streaming
+            // notification comes in before the user has yet taken
+            // us into the activity reading that feed. If so,
+            // ignore the event; the _actual_ initial fetch will
+            // deal with it later.
+            return Ok(false);
         }
 
         let req = match id {
@@ -649,7 +644,7 @@ impl Client {
 
         let req = match ext {
             FeedExtend::Initial => req.param("limit", 32),
-            FeedExtend::Past => if let Some(ref feed) = self.feeds.get(&id) {
+            FeedExtend::Past => if let Some(feed) = self.feeds.get(id) {
                 match feed.extend_past {
                     None => return Ok(false),
                     Some(ref params) => {
@@ -661,7 +656,7 @@ impl Client {
                     }
                 }
             } else { req },
-            FeedExtend::Future => if let Some(ref feed) = self.feeds.get(&id) {
+            FeedExtend::Future => if let Some(feed) = self.feeds.get(id) {
                 match feed.extend_future {
                     None => return Ok(false),
                     Some(ref params) => {
@@ -679,7 +674,7 @@ impl Client {
         let rspstatus = rsp.status();
         if !rspstatus.is_success() {
             return Err(ClientError::UrlError(
-                url.clone(), rspstatus.to_string()));
+                url, rspstatus.to_string()));
         }
 
         // Keep the Link: headers after we consume the response, for
@@ -850,7 +845,7 @@ impl Client {
             match rsp.headers().get(reqwest::header::LOCATION) {
                 None => {
                     return Err(ClientError::UrlError(
-                        url.clone(),
+                        url,
                         "received redirection without a Location header"
                             .to_owned()));
                 }
@@ -880,7 +875,7 @@ impl Client {
                     };
                     if !ok {
                         return Err(ClientError::UrlError(
-                            url.clone(),
+                            url,
                             format!("redirection to suspicious URL {}",
                                     sval)));
                     }
@@ -897,7 +892,7 @@ impl Client {
         let rspstatus = rsp.status();
         if !rspstatus.is_success() {
             return Err(ClientError::UrlError(
-                url.clone(), rspstatus.to_string()));
+                url, rspstatus.to_string()));
         }
 
         let id = id.clone();
@@ -922,7 +917,7 @@ impl Client {
                         // connection timing out. We don't communicate
                         // them back to the main thread.
                     } else {
-                        let rsp = match std::str::from_utf8(&line) {
+                        let rsp = match std::str::from_utf8(line) {
                             Err(_) => StreamResponse::BadUTF8,
                             Ok(d) => StreamResponse::Line(d.to_owned()),
                         };
@@ -993,12 +988,12 @@ impl Client {
             Req::get("v1/accounts/lookup").param("acct", name))?;
         let rspstatus = rsp.status();
         let ac: Account = if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             match serde_json::from_str(&rsp.text()?) {
                 Ok(ac) => Ok(ac),
                 Err(e) => Err(ClientError::UrlError(
-                    url.clone(), e.to_string())),
+                    url, e.to_string())),
             }
         }?;
         self.cache_account(&ac);
@@ -1026,7 +1021,7 @@ impl Client {
         let (url, rsp) = self.api_request(req)?;
         let rspstatus = rsp.status();
         if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             Ok(())
         }
@@ -1040,12 +1035,12 @@ impl Client {
         let rspstatus = rsp.status();
         // Cache the returned status so as to update its faved/boosted flags
         let st: Status = if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             match serde_json::from_str(&rsp.text()?) {
                 Ok(st) => Ok(st),
                 Err(e) => {
-                    Err(ClientError::UrlError(url.clone(), e.to_string()))
+                    Err(ClientError::UrlError(url, e.to_string()))
                 }
             }
         }?;
@@ -1073,12 +1068,12 @@ impl Client {
             &format!("v1/statuses/{id}/context")))?;
         let rspstatus = rsp.status();
         let ctx: Context = if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             match serde_json::from_str(&rsp.text()?) {
                 Ok(st) => Ok(st),
                 Err(e) => {
-                    Err(ClientError::UrlError(url.clone(), e.to_string()))
+                    Err(ClientError::UrlError(url, e.to_string()))
                 }
             }
         }?;
index 574d055a7ec0aed4bc2547d07072c0fdd5208710..885649f76e85d048b75de8cd841cb50adf43924c 100644 (file)
@@ -87,8 +87,8 @@ 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 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()
@@ -139,8 +139,8 @@ impl std::ops::Add<ColouredStringSlice<'_>> for ColouredString {
     type Output = ColouredString;
     fn add(self, rhs: ColouredStringSlice<'_>) -> ColouredString {
         ColouredString {
-            text: self.text.to_owned() + &rhs.text,
-            colour: self.colour.to_owned() + &rhs.colour,
+            text: self.text + rhs.text,
+            colour: self.colour + rhs.colour,
         }
     }
 }
@@ -283,10 +283,7 @@ impl<'a> Iterator for ColouredStringFragIterator<'a> {
 }
 
 fn char_width_infallible(c: char) -> usize {
-    match UnicodeWidthChar::width(c) {
-        Some(w) => w,
-        None => 0,
-    }
+    UnicodeWidthChar::width(c).unwrap_or(0)
 }
 
 impl<'a> Iterator for ColouredStringSplitIterator<'a> {
index d357d967d389cf08f4603a28f20e04df22603453..f452a77c6db772453818ac865326827ab1bb4454 100644 (file)
@@ -228,36 +228,36 @@ fn test_forward_backward() {
         paste_buffer: "".to_owned(),
     };
 
-    assert_eq!(ec.forward(), true);
+    assert!(ec.forward());
     assert_eq!(ec.point, 1);
-    assert_eq!(ec.forward(), true);
+    assert!(ec.forward());
     assert_eq!(ec.point, 3);
-    assert_eq!(ec.forward(), true);
+    assert!(ec.forward());
     assert_eq!(ec.point, 4);
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, 3);
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, 1);
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, 0);
-    assert_eq!(ec.backward(), false);
+    assert!(!ec.backward());
 
     ec.point = ec.text.len() - 2;
-    assert_eq!(ec.forward(), true);
+    assert!(ec.forward());
     assert_eq!(ec.point, ec.text.len() - 1);
-    assert_eq!(ec.forward(), true);
+    assert!(ec.forward());
     assert_eq!(ec.point, ec.text.len());
-    assert_eq!(ec.forward(), false);
+    assert!(!ec.forward());
     assert_eq!(ec.point, ec.text.len());
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, ec.text.len() - 1);
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, ec.text.len() - 2);
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, ec.text.len() - 3);
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, ec.text.len() - 5);
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
 }
 
 #[test]
@@ -268,29 +268,29 @@ fn test_forward_backward_word() {
         paste_buffer: "".to_owned(),
     };
 
-    assert_eq!(ec.forward_word(), true);
+    assert!(ec.forward_word());
     assert_eq!(ec.point, 6);    // ipsum
-    assert_eq!(ec.forward_word(), true);
+    assert!(ec.forward_word());
     assert_eq!(ec.point, 12);   // dolor
-    assert_eq!(ec.forward_word(), true);
+    assert!(ec.forward_word());
     assert_eq!(ec.point, 18);   // sit
-    assert_eq!(ec.forward_word(), true);
+    assert!(ec.forward_word());
     assert_eq!(ec.point, 22);   // amet
-    assert_eq!(ec.forward_word(), true);
+    assert!(ec.forward_word());
     assert_eq!(ec.point, 26);   // end of string
-    assert_eq!(ec.forward_word(), false);
+    assert!(!ec.forward_word());
 
-    assert_eq!(ec.backward_word(), true);
+    assert!(ec.backward_word());
     assert_eq!(ec.point, 22);   // amet
-    assert_eq!(ec.backward_word(), true);
+    assert!(ec.backward_word());
     assert_eq!(ec.point, 18);   // sit
-    assert_eq!(ec.backward_word(), true);
+    assert!(ec.backward_word());
     assert_eq!(ec.point, 12);   // dolor
-    assert_eq!(ec.backward_word(), true);
+    assert!(ec.backward_word());
     assert_eq!(ec.point, 6);    // ipsum
-    assert_eq!(ec.backward_word(), true);
+    assert!(ec.backward_word());
     assert_eq!(ec.point, 0);    // lorem
-    assert_eq!(ec.backward_word(), false);
+    assert!(!ec.backward_word());
 }
 
 #[test]
@@ -347,7 +347,7 @@ fn test_insert() {
 
     // But then moving backwards one character goes back over the
     // combining char and the printing one before it
-    assert_eq!(ec.backward(), true);
+    assert!(ec.backward());
     assert_eq!(ec.point, 3);
 
     ec.paste_buffer = "PASTE".to_owned();
@@ -454,7 +454,7 @@ impl SingleLineEditor {
             _ => { self.core.handle_keypress(key); }
         }
         self.update_first_visible();
-        return false;
+        false
     }
 
     pub fn borrow_text(&self) -> &str { &self.core.text }
@@ -669,7 +669,7 @@ pub fn get_user_to_examine() -> Box<dyn ActivityState> {
         ColouredString::plain("Examine User: "),
         Box::new(move |s, client| {
             let s = s.trim();
-            let s = s.strip_prefix("@").unwrap_or(s);
+            let s = s.strip_prefix('@').unwrap_or(s);
             if s.is_empty() {
                 LogicalAction::PopOverlaySilent
             } else {
@@ -714,7 +714,7 @@ pub fn get_hashtag_to_read() -> Box<dyn ActivityState> {
         ColouredString::plain("View feed for hashtag: "),
         Box::new(move |s, _client| {
             let s = s.trim();
-            let s = s.strip_prefix("#").unwrap_or(s);
+            let s = s.strip_prefix('#').unwrap_or(s);
             if s.is_empty() {
                 LogicalAction::PopOverlaySilent
             } else {
@@ -1139,7 +1139,7 @@ impl Composer {
             // the empty line it left behind. But we don't put that
             // boring \n in the paste buffer.
             self.core.delete(self.core.point, eol_pos);
-        } else if slice.ends_with("\n") {
+        } else if slice.ends_with('\n') {
             // If the slice goes up to but not including a \n,
             // literally cut everything up to but not including the
             // end of the line.
@@ -1169,7 +1169,7 @@ impl Composer {
         let detect_magic_sequence = |seq: &str| {
             self.core.text[..self.core.point].ends_with(seq) &&
                 (self.core.point == seq.len() ||
-                 self.core.text[..self.core.point - seq.len()].ends_with("\n"))
+                 self.core.text[..self.core.point - seq.len()].ends_with('\n'))
         };
 
         if detect_magic_sequence(".\n") {
@@ -1187,7 +1187,7 @@ impl Composer {
     }
 
     fn submit_post(&self) -> LogicalAction {
-        return LogicalAction::PostComposed(Post {
+        LogicalAction::PostComposed(Post {
             text: self.core.text.clone(),
             m: self.post_metadata.clone(),
         })
@@ -1452,7 +1452,7 @@ impl ActivityState for Composer {
         match (self.keystate, key) {
             (Start, Ctrl('N')) | (Start, Down) |
             (Start, Ctrl('P')) | (Start, Up) => {
-                if !self.goal_column.is_some() {
+                if self.goal_column.is_none() {
                     self.goal_column = self.cursor_pos.map(|(x, _y)| x);
                 }
             }
@@ -1519,9 +1519,7 @@ pub fn compose_post(client: &mut Client, post: Post) ->
         Some(ref id) => format!("Reply to post {id}"),
     };
     let header = FileHeader::new(ColouredString::uniform(&title, 'H'));
-    let irt = match post.m.in_reply_to_id {
-        None => None,
-        Some(ref id) => Some(InReplyToLine::from_id(id, client)),
-    };
+    let irt = post.m.in_reply_to_id.as_ref()
+        .map(|id| InReplyToLine::from_id(id, client));
     Ok(Box::new(Composer::new(inst.configuration.statuses, header, irt, post)))
 }
index 39e5a60a77a7f46fa3a8fd979b401f4510e68bb3..408eb93d724160a3dcb8727520c0366b5ad65dad 100644 (file)
@@ -63,7 +63,7 @@ impl FeedSource {
 impl FileDataSource for FeedSource {
     fn get(&self, client: &mut Client) -> (Vec<String>, isize) {
         let feed = client.borrow_feed(&self.id);
-        let ids = feed.ids.iter().map(|x| x.clone()).collect();
+        let ids = feed.ids.iter().cloned().collect();
         (ids, feed.origin)
     }
 
@@ -145,8 +145,8 @@ impl FileType for StatusFeedType {
     fn get_from_client(id: &str, client: &mut Client) ->
         Result<Self::Item, ClientError>
     {
-        let st = client.status_by_id(&id)?;
-        Ok(StatusDisplay::new(st.clone(), client))
+        let st = client.status_by_id(id)?;
+        Ok(StatusDisplay::new(st, client))
     }
 
     fn feed_id(&self) -> Option<&FeedId> { self.id.as_ref() }
@@ -164,7 +164,7 @@ impl FileType for NotificationStatusFeedType {
     fn get_from_client(id: &str, client: &mut Client) ->
         Result<Self::Item, ClientError>
     {
-        let not = client.notification_by_id(&id)?;
+        let not = client.notification_by_id(id)?;
         let st = &not.status.expect(
             "expected all notifications in this feed would have statuses");
         Ok(StatusDisplay::new(st.clone(), client))
@@ -185,7 +185,7 @@ impl FileType for EgoNotificationFeedType {
     fn get_from_client(id: &str, client: &mut Client) ->
         Result<Self::Item, ClientError>
     {
-        let not = client.notification_by_id(&id)?;
+        let not = client.notification_by_id(id)?;
         Ok(NotificationLog::from_notification(&not, client))
     }
 
@@ -199,7 +199,7 @@ impl FileType for UserListFeedType {
     fn get_from_client(id: &str, client: &mut Client) ->
         Result<Self::Item, ClientError>
     {
-        let ac = client.account_by_id(&id)?;
+        let ac = client.account_by_id(id)?;
         Ok(UserListEntry::from_account(&ac, client))
     }
 }
@@ -407,7 +407,7 @@ impl<Type: FileType, Source: FileDataSource> File<Type, Source> {
             }
         }
 
-        if lines_rendered + 1 <= h {
+        if lines_rendered < h {
             Some(h - 1 - lines_rendered)
         } else {
             None
@@ -418,12 +418,9 @@ impl<Type: FileType, Source: FileDataSource> File<Type, Source> {
         let (w, _h) = self.last_size.expect(
             "ensure_enough_rendered before setting pos");
         let at_top = self.at_top();
-        match &mut self.contents.extender {
-            Some(ref mut ext) => {
-                ext.set_primed(at_top);
-            }
-            _ => (),
-        };
+        if let Some(ref mut ext) = &mut self.contents.extender {
+            ext.set_primed(at_top);
+        }
         if let Some(ei) = self.contents.extender_index() {
             self.rendered.remove(&ei);
             self.ensure_item_rendered(ei, w);
@@ -431,7 +428,7 @@ impl<Type: FileType, Source: FileDataSource> File<Type, Source> {
     }
 
     fn update_pos_for_size(&mut self, w: usize, h: usize) {
-        if self.pos.width == None && self.pos.line == 0 {
+        if self.pos.width.is_none() && self.pos.line == 0 {
             // Special case: look at the _top_ of the item
             self.pos.width = Some(w);
             self.move_down(h.saturating_sub(1));
@@ -606,12 +603,10 @@ impl<Type: FileType, Source: FileDataSource> File<Type, Source> {
             self.rerender_selected_item();
             self.ensure_enough_rendered();
             LogicalAction::Nothing
+        } else if none_ok {
+            LogicalAction::Nothing
         } else {
-            if none_ok {
-                LogicalAction::Nothing
-            } else {
-                LogicalAction::Beep
-            }
+            LogicalAction::Beep
         };
 
         self.select_aux = match self.ui_mode {
@@ -769,7 +764,7 @@ impl<Type: FileType, Source: FileDataSource> File<Type, Source> {
 
     fn search(&mut self) -> LogicalAction {
         if let Some(dir) = self.search_direction {
-            if !self.last_search.is_some() {
+            if self.last_search.is_none() {
                 return LogicalAction::Beep;
             }
 
@@ -948,8 +943,8 @@ impl<Type: FileType, Source: FileDataSource>
                 fs.add(Pr('Q'), "Quit", 100)
             }
             UIMode::PostsSubmenu => {
-                assert_eq!(Type::CAN_GET_POSTS, true,
-                           "How did we get here if !CAN_GET_POSTS?");
+                assert!(Type::CAN_GET_POSTS,
+                        "How did we get here if !CAN_GET_POSTS?");
                 fs.add(Pr('A'), "All", 99)
                     .add(Pr('O'), "Original", 97)
                     .add(Pr('T'), "Top-level", 98)
@@ -1356,7 +1351,7 @@ pub fn list_status_boosters(client: &mut Client, id: &str) ->
 pub fn list_user_followers(client: &mut Client, id: &str) ->
     Result<Box<dyn ActivityState>, ClientError>
 {
-    let ac = client.account_by_id(&id)?;
+    let ac = client.account_by_id(id)?;
     let name = client.fq(&ac.acct);
 
     let file = File::new(
@@ -1370,7 +1365,7 @@ pub fn list_user_followers(client: &mut Client, id: &str) ->
 pub fn list_user_followees(client: &mut Client, id: &str) ->
     Result<Box<dyn ActivityState>, ClientError>
 {
-    let ac = client.account_by_id(&id)?;
+    let ac = client.account_by_id(id)?;
     let name = client.fq(&ac.acct);
 
     let file = File::new(
@@ -1387,7 +1382,7 @@ pub fn hashtag_timeline(client: &mut Client, tag: &str) ->
     let title = ColouredString::uniform(
         &format!("Posts mentioning hashtag #{tag}"), 'H');
     let feed = FeedId::Hashtag(tag.to_owned());
-    let desc = StatusFeedType::with_feed(feed.clone());
+    let desc = StatusFeedType::with_feed(feed);
     let file = File::new(
         client, FeedSource::new(FeedId::Hashtag(tag.to_owned())), title,
         desc, None)?;
@@ -1404,7 +1399,7 @@ impl FileType for ExamineUserFileType {
         Result<Self::Item, ClientError>
     {
         let ac = client.account_by_id(id)?;
-        Ok(ExamineUserDisplay::new(ac, client)?)
+        ExamineUserDisplay::new(ac, client)
     }
 }
 
@@ -1430,8 +1425,8 @@ impl FileType for DetailedStatusFileType {
     fn get_from_client(id: &str, client: &mut Client) ->
         Result<Self::Item, ClientError>
     {
-        let st = client.status_by_id(&id)?;
-        Ok(DetailedStatusDisplay::new(st.clone(), client))
+        let st = client.status_by_id(id)?;
+        Ok(DetailedStatusDisplay::new(st, client))
     }
 }
 
@@ -1487,6 +1482,6 @@ pub fn view_thread(client: &mut Client, start_id: &str, full: bool) ->
     let file = File::new(
         client, StaticSource::vector(ids), title,
         StatusFeedType::without_feed(),
-        Some(FilePosition::item_top(index as isize)))?;
+        Some(FilePosition::item_top(index)))?;
     Ok(Box::new(file))
 }
index 30188b4f1d3a7ada6b998b443cace16232d5291e..9e4debed905f965a5a57d5820b539767ca489a37 100644 (file)
@@ -47,7 +47,7 @@ impl<'a> TextDecorator for OurDecorator<'a> {
     /// Return a suffix for after a link.
     fn decorate_link_end(&mut self) -> String {
         if let Some(url) = self.current_url.take() {
-            if let Some(ref rc) = self.urls {
+            if let Some(rc) = self.urls {
                 // This is safe because the borrow only lasts for the
                 // duration of this Vec::push, and it's the only
                 // borrow_mut of this RefCell anywhere, so nothing is
@@ -123,7 +123,7 @@ impl<'a> TextDecorator for OurDecorator<'a> {
     /// Return a new decorator of the same type which can be used
     /// for sub blocks.
     fn make_subblock_decorator(&self) -> Self {
-        OurDecorator::with_option_urls(self.urls.clone())
+        OurDecorator::with_option_urls(self.urls)
     }
 
     /// Return an annotation corresponding to adding colour, or none.
@@ -183,7 +183,7 @@ fn render_tl(rt: &RenderTree, width: usize) -> Vec<TaggedLine<Vec<char>>> {
         let mut w = width;
         loop {
             w += w / 2;
-            if let Ok(_) = try_render(rt, width, w) {
+            if try_render(rt, width, w).is_ok() {
                 break w;
             }
         }
@@ -191,7 +191,7 @@ fn render_tl(rt: &RenderTree, width: usize) -> Vec<TaggedLine<Vec<char>>> {
 
     while wgood - wbad > 1 {
         let wmid = wbad + (wgood - wbad) / 2;
-        if let Ok(_) = try_render(rt, width, wmid) {
+        if try_render(rt, width, wmid).is_ok() {
             wgood = wmid;
         } else {
             wbad = wmid;
@@ -205,15 +205,12 @@ fn render_tl(rt: &RenderTree, width: usize) -> Vec<TaggedLine<Vec<char>>> {
 fn to_coloured_string(tl: &TaggedLine<Vec<char>>) -> ColouredString {
     let mut cs = ColouredString::plain("");
     for e in tl.iter() {
-        match e {
-            TaggedLineElement::Str(ts) => {
-                let c: char = match ts.tag.first() {
-                    Some(c) => *c,
-                    None => ' ',
-                };
-                cs.push_str(&ColouredString::uniform(&ts.s, c).slice());
-            }
-            _ => (),
+        if let TaggedLineElement::Str(ts) = e {
+            let c: char = match ts.tag.first() {
+                Some(c) => *c,
+                None => ' ',
+            };
+            cs.push_str(&ColouredString::uniform(&ts.s, c).slice());
         }
     }
     cs
index 7c771ef313c3c294f440e70c10169ebd128b1b69..867d8020ca56b1c220df61fa03f66ccd436be84c 100644 (file)
@@ -20,7 +20,7 @@ enum AppTokenType<'a> {
 }
 use AppTokenType::*;
 
-const REDIRECT_MAGIC_STRING: &'static str = "urn:ietf:wg:oauth:2.0:oob";
+const REDIRECT_MAGIC_STRING: &str = "urn:ietf:wg:oauth:2.0:oob";
 
 impl Login {
     fn new(instance_url: &str, logfile: Option<File>)
@@ -52,12 +52,11 @@ impl Login {
         let rsp = self.execute_request(req)?;
         let rspstatus = rsp.status();
         if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             let app: Application = match serde_json::from_str(&rsp.text()?) {
                 Ok(app) => Ok(app),
-                Err(e) => Err(ClientError::UrlError(
-                    url.clone(), e.to_string())),
+                Err(e) => Err(ClientError::UrlError(url, e.to_string())),
             }?;
             Ok(app)
         }
@@ -91,12 +90,11 @@ impl Login {
         let rsp = self.execute_request(req)?;
         let rspstatus = rsp.status();
         if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             let tok: Token = match serde_json::from_str(&rsp.text()?) {
                 Ok(tok) => Ok(tok),
-                Err(e) => Err(ClientError::UrlError(
-                    url.clone(), e.to_string())),
+                Err(e) => Err(ClientError::UrlError(url, e.to_string())),
             }?;
             Ok(tok)
         }
@@ -110,12 +108,11 @@ impl Login {
         let rsp = self.execute_request(req)?;
         let rspstatus = rsp.status();
         if !rspstatus.is_success() {
-            Err(ClientError::UrlError(url.clone(), rspstatus.to_string()))
+            Err(ClientError::UrlError(url, rspstatus.to_string()))
         } else {
             let tok: T = match serde_json::from_str(&rsp.text()?) {
                 Ok(tok) => Ok(tok),
-                Err(e) => Err(ClientError::UrlError(
-                    url.clone(), e.to_string())),
+                Err(e) => Err(ClientError::UrlError(url, e.to_string())),
             }?;
             Ok(tok)
         }
@@ -178,9 +175,9 @@ pub fn login(cfgloc: &ConfigLocation, instance_url: &str,
     // Print it
     println!("Log in to the website {instance_url}/");
     println!("and then visit this URL to authorise Mastodonochrome:");
-    println!("");
+    println!();
     println!("{}", url);
-    println!("");
+    println!();
     println!("If you click \"Authorise\" on that page, you should receive a response code.");
     print!("Enter that code here: ");
     std::io::stdout().flush().unwrap(); // FIXME
@@ -191,7 +188,7 @@ pub fn login(cfgloc: &ConfigLocation, instance_url: &str,
         std::io::stdin().read_line(&mut buf).unwrap(); // FIXME
         buf
     };
-    let code = (&code).trim_end();
+    let code = code.trim_end();
 
     // Use that code to get the final user access token
     let user_token = login.get_token(&app, AuthorizationCode(code))?;
@@ -200,7 +197,7 @@ pub fn login(cfgloc: &ConfigLocation, instance_url: &str,
     let instance: Instance = login.get("/api/v2/instance",
                                        &user_token.access_token)?;
 
-    println!("");
+    println!();
     println!("Successfully logged in as {}@{}", account.username, instance.domain);
     println!("Now run 'mastodonochrome' without arguments to read and post!");
 
index 7bee2fb500226c1a6349a9eb02c7710dc8a32653..00df08d833b6117fc88b2526e71ab9e63f7f1168 100644 (file)
@@ -47,7 +47,7 @@ fn main() -> ExitCode {
     match main_inner() {
         Ok(_) => ExitCode::from(0),
         Err(e) => {
-            let _ = eprintln!("{}", e);
+            eprintln!("{}", e);
             ExitCode::from(1)
         }
     }
index e720d83b4818378394907d490c5b2ecf2410deb4..cae15938087df610eaed7de26454e711a23060c0 100644 (file)
@@ -30,7 +30,7 @@ pub struct Post {
 fn default_language() -> String {
     get_locale().as_deref()
         .and_then(|s| s.split('-').next())
-        .map(|s| if s.len() == 0 { "en" } else { s })
+        .map(|s| if s.is_empty() { "en" } else { s })
         .unwrap_or("en")
         .to_owned()
 }
@@ -172,7 +172,7 @@ impl PostMenu {
             check_widths(&Self::visibility_item(vis));
         }
         if let Some(ref ml) = self.editor_prompt {
-            check_widths(&ml);
+            check_widths(ml);
         }
 
         self.ml_post.reset_widths();
index adc38446c61d3505bbf48ccd159cdcfa7986386d..2b16b144b1c3537bf51eca13299e00a3b472ab41 100644 (file)
@@ -11,7 +11,7 @@ impl Findable {
     pub fn get_span(&self, text: &str, start: usize) -> Option<(usize, usize)> {
         let mut start = start;
         loop {
-            match self.text.find_at(&text, start) {
+            match self.text.find_at(text, start) {
                 None => break None,
                 Some(m) => {
                     let (ms, me) = (m.start(), m.end());
@@ -63,8 +63,8 @@ impl Scan {
         let mention_bad_pre = Regex::new(&("[=/".to_owned() + word + "]$"))
             .unwrap();
         let mention = Regex::new(
-            &("(?i:@((".to_owned() + &username + ")(?:@[" + &word + ".-]+[" +
-              &word + "]+)?))")).unwrap();
+            &("(?i:@((".to_owned() + username + ")(?:@[" + word + ".-]+[" +
+              word + "]+)?))")).unwrap();
 
         let hashtag_separators = "_\u{B7}\u{30FB}\u{200C}";
         let word_hash_sep = word.to_owned() + "#" + hashtag_separators;
@@ -97,9 +97,9 @@ impl Scan {
         let domain = domain_component.to_owned() + "(?:\\." +
             &domain_component + ")*";
 
-        let path_end_chars = "a-z".to_owned() + &cyrillic + &accented +
+        let path_end_chars = "a-z".to_owned() + cyrillic + accented +
             "0-9=_#/\\+\\-";
-        let path_mid_chars = path_end_chars.to_owned() + &pd +
+        let path_mid_chars = path_end_chars.to_owned() + pd +
             "!\\*\\';:\\,\\.\\$\\%\\[\\]~&\\|@";
 
         let path_bracketed_once = "\\([".to_owned() +
@@ -118,7 +118,7 @@ impl Scan {
             "!?\\*\\'\\(\\);:\\+\\$%\\[\\]\\.,~|@";
 
         let url_bad_pre = Regex::new(
-            &("[A-Z0-9@$#\u{FF20}\u{FF03}".to_owned() + &directional + "]$"))
+            &("[A-Z0-9@$#\u{FF20}\u{FF03}".to_owned() + directional + "]$"))
             .unwrap();
         let url = Regex::new(
             &("(?i:".to_owned() +
index e8827536253366f1ee774827939d438036fd2789..a2bfd70078cb306ccf58ffe2c74d618477543929 100644 (file)
@@ -141,9 +141,10 @@ impl<T: TextFragment> TextFragment for Vec<T> {
     fn highlighted_id(&self, highlight: Option<Highlight>) -> Option<String> {
         let mut highlight = highlight;
         for item in self {
-            match item.highlighted_id_update(&mut highlight) {
-                result @ Some(..) => return result,
-                _ => (),
+            if let result @ Some(..) = item.highlighted_id_update(
+                &mut highlight)
+            {
+                return result;
             }
         }
         None
@@ -210,14 +211,11 @@ impl TextFragment for SeparatorLine {
         let mut suffix = ColouredString::plain("");
         let display_pre = ColouredString::uniform("[", 'S');
         let display_post = ColouredString::uniform("]--", 'S');
-        match self.timestamp {
-            Some(date) => {
-                let datestr = format_date(date);
-                suffix = &display_pre +
-                    ColouredString::uniform(&datestr, 'D') +
-                    &display_post + suffix;
-            }
-            _ => (),
+        if let Some(date) = self.timestamp {
+            let datestr = format_date(date);
+            suffix = &display_pre +
+                ColouredString::uniform(&datestr, 'D') +
+                &display_post + suffix;
         }
         if self.boosted {
             suffix = &display_pre + ColouredString::uniform("B", 'D') +
@@ -266,7 +264,7 @@ impl TextFragment for EditorHeaderSeparator {
     {
         vec! {
             ColouredString::uniform(
-                &((&"-".repeat(width - min(2, width))).to_owned() + "|"),
+                &("-".repeat(width - min(2, width)) + "|"),
                 '-',
             ).truncate(width).to_owned(),
         }
@@ -920,9 +918,7 @@ impl InReplyToLine {
         let currlen = para.words.len();
         para.push_para(&post);
         para.delete_mention_words_from(currlen);
-        InReplyToLine {
-            para: para
-        }
+        InReplyToLine { para }
     }
 
     pub fn from_id(id: &str, client: &mut Client) -> Self {
@@ -1036,10 +1032,7 @@ impl NotificationLog {
             para.delete_mention_words_from(currlen);
         }
 
-        let status_id = match status_id {
-            None => None,
-            Some(s) => Some(s.to_owned()),
-        };
+        let status_id = status_id.map(|s| s.to_owned());
 
         NotificationLog {
             timestamp,
@@ -1051,14 +1044,9 @@ impl NotificationLog {
     }
 
     pub fn from_notification(not: &Notification, client: &mut Client) -> Self {
-        let para = match &not.status {
-            None => None,
-            Some(st) => Some(Html::new(&st.content).to_para()),
-        };
-        let status_id = match &not.status {
-            None => None,
-            Some(st) => Some(&st.id as &str),
-        };
+        let para = not.status.as_ref()
+            .map(|st| Html::new(&st.content).to_para());
+        let status_id = not.status.as_ref().map(|st| &st.id as &str);
         Self::new(
             not.created_at,
             &client.fq(&not.account.acct),
@@ -1386,7 +1374,7 @@ impl FileStatusLine {
 
         FileStatusLineFinal {
             fs: self,
-            priwidth: priwidth
+            priwidth,
         }
     }
 }
@@ -1461,19 +1449,16 @@ impl TextFragment for FileStatusLineFinal {
         };
 
         if let Some(msg) = &self.fs.message {
-            let cmsg = ColouredString::plain(&msg);
+            let cmsg = ColouredString::plain(msg);
             push(&mut line, cmsg.slice());
         }
 
-        let cprop = if let Some(prop) = &self.fs.proportion {
-            Some(ColouredString::plain(&format!("({}%)", prop)))
-        } else {
-            None
-        };
+        let cprop = self.fs.proportion.as_ref()
+            .map(|prop| ColouredString::plain(&format!("({}%)", prop)));
         let cpropwidth = if let Some(cprop) = &cprop { cprop.width() } else {0};
         let extraspace = if !line.is_empty() && cpropwidth > 0 {
             FileStatusLine::SPACING
-        } else if !cprop.is_some() {
+        } else if cprop.is_none() {
             1 // trailing '.' if no proportion
         } else {
             0
@@ -1759,10 +1744,8 @@ impl StatusDisplay {
                 &booster.id)),
         };
 
-        let irt = match &st.in_reply_to_id {
-            None => None,
-            Some(id) => Some(InReplyToLine::from_id(id, client)),
-        };
+        let irt = st.in_reply_to_id.as_ref()
+            .map(|id| InReplyToLine::from_id(id, client));
 
         let vis = match st.visibility {
             Visibility::Public => None,
@@ -1772,10 +1755,7 @@ impl StatusDisplay {
         let content = Html::new(&st.content);
 
         let media = st.media_attachments.iter().map(|m| {
-            let desc_ref = match &m.description {
-                Some(s) => Some(&s as &str),
-                None => None,
-            };
+            let desc_ref = m.description.as_ref().map(|s| s as &str);
             Media::new(&m.url, desc_ref)
         }).collect();
 
@@ -1788,7 +1768,7 @@ impl StatusDisplay {
             content,
             media,
             blank: BlankLine::new(),
-            id: st.id.clone(),
+            id: st.id,
         }
     }
 
@@ -1828,7 +1808,7 @@ impl TextFragment for StatusDisplay {
         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;
+        let content_empty = rendered_content.is_empty();
         push_fragment_opt_highlight(&mut lines, rendered_content);
         if !content_empty {
             push_fragment(&mut lines, self.blank.render(width));
@@ -1861,13 +1841,15 @@ impl TextFragment for StatusDisplay {
         match highlight {
             Some(Highlight(HighlightType::User, _)) => {
                 let mut highlight = highlight;
-                match self.from.highlighted_id_update(&mut highlight) {
-                    result @ Some(..) => return result,
-                    _ => (),
+                if let result @ Some(..) = self.from.highlighted_id_update(
+                    &mut highlight)
+                {
+                    return result;
                 }
-                match self.via.highlighted_id_update(&mut highlight) {
-                    result @ Some(..) => return result,
-                    _ => (),
+                if let result @ Some(..) = self.via.highlighted_id_update(
+                    &mut highlight)
+                {
+                    return result;
                 }
                 None
             }
@@ -1990,15 +1972,15 @@ impl DetailedStatusDisplay {
         let client_url = Paragraph::new()
             .add(&ColouredString::plain("Client website: "))
             .add(&st.application.as_ref()
-                 .map_or(None, |app| app.website.as_ref())
+                 .and_then(|app| app.website.as_ref())
                  .map_or_else(
                      || ColouredString::uniform("none", '0'),
-                     |url| ColouredString::uniform(&url, 'u')));
+                     |url| ColouredString::uniform(url, 'u')));
 
         let sd = StatusDisplay::new(st, client);
         let urls: Vec<_> = sd.list_urls().iter().map(|u| {
             Paragraph::new().set_indent(2, 4)
-                .add(&ColouredString::uniform(&u, 'u'))
+                .add(&ColouredString::uniform(u, 'u'))
         }).collect();
         let urls_header = if urls.is_empty() {
             None
@@ -2135,9 +2117,10 @@ impl TextFragment for DetailedStatusDisplay {
                       -> Option<String>
     {
         let mut highlight = highlight;
-        match self.sd.highlighted_id_update(&mut highlight) {
-            result @ Some(..) => return result,
-            _ => (),
+        if let result @ Some(..) = self.sd.highlighted_id_update(
+            &mut highlight)
+        {
+            return result;
         }
 
         match highlight {
@@ -2207,7 +2190,7 @@ impl ExamineUserDisplay {
         let info_fields = ac.fields.iter().map(|field| {
             let colour = if field.verified_at.is_some() { 'f' } else { ' ' };
             let title_text = field.name.trim();
-            let title_text = title_text.strip_suffix(":").unwrap_or(title_text);
+            let title_text = title_text.strip_suffix(':').unwrap_or(title_text);
             let title_text = title_text.to_owned() + ":";
             let title = Paragraph::new()
                 .add(&ColouredString::uniform(&title_text, colour))
@@ -2337,7 +2320,7 @@ impl ExamineUserDisplay {
                     &format!("Unable to retrieve relationships: {}", e),
                     '!'))),
         }
-        if relationships.len() > 0 {
+        if !relationships.is_empty() {
             relationships.insert(0, Paragraph::new().add(
                 &ColouredString::plain("Relationships to this user:")));
         }
index 52c90a28f0c04ff6b21042e97cea93d19c953732..f8fe3609049046f8eeaeab221d25aa1ac3d571b0 100644 (file)
@@ -216,7 +216,7 @@ impl Tui {
         // I don't think we have any need to join subthreads like this
         let _joinhandle = std::thread::spawn(move || {
             while let Ok(ev) = event::read() {
-                if let Err(_) = input_sender.send(SubthreadEvent::TermEv(ev)) {
+                if input_sender.send(SubthreadEvent::TermEv(ev)).is_err() {
                     break;
                 }
             }
@@ -304,8 +304,8 @@ impl Tui {
             let sender = self.subthread_sender.clone();
             self.client.start_streaming_thread(
                 &StreamId::User, Box::new(move |update| {
-                    if let Err(_) = sender.send(
-                        SubthreadEvent::StreamEv(update)) {
+                    if sender.send(
+                        SubthreadEvent::StreamEv(update)).is_err() {
                     // It would be nice to do something about this
                     // error, but what _can_ we do? We can hardly send
                     // an error notification back to the main thread,
@@ -581,7 +581,7 @@ impl TuiLogicalState {
                             NonUtilityActivity::ComposeToplevel) =>
                             NonUtilityActivity::PostComposeMenu.into(),
                         Activity::Util(UtilityActivity::ComposeReply(id)) =>
-                            UtilityActivity::PostReplyMenu(id.clone()).into(),
+                            UtilityActivity::PostReplyMenu(id).into(),
                         act => panic!("can't postcompose {act:?}"),
                     };
                     self.activity_stack.chain_to(newact);
@@ -593,7 +593,7 @@ impl TuiLogicalState {
                         Activity::NonUtil(NonUtilityActivity::PostComposeMenu) =>
                             NonUtilityActivity::ComposeToplevel.into(),
                         Activity::Util(UtilityActivity::PostReplyMenu(id)) =>
-                            UtilityActivity::ComposeReply(id.clone()).into(),
+                            UtilityActivity::ComposeReply(id).into(),
                         act => panic!("can't reedit {act:?}"),
                     };
                     self.activity_stack.chain_to(newact);
@@ -683,7 +683,7 @@ impl TuiLogicalState {
             Activity::Util(UtilityActivity::InfoStatus(ref id)) =>
                 view_single_post(client, id),
             Activity::NonUtil(NonUtilityActivity::ComposeToplevel) =>
-                compose_post(client, post.unwrap_or_else(|| Post::new())),
+                compose_post(client, post.unwrap_or_else(Post::new)),
             Activity::NonUtil(NonUtilityActivity::PostComposeMenu) =>
                 Ok(post_menu(post.expect(
                     "how did we get here without a Post?"))),