From: Simon Tatham Date: Sat, 6 Jan 2024 00:23:00 +0000 (+0000) Subject: Apply many uncontroversial style fixes from Clippy. X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=a3f63d1e9d2f9f46e430a8f3f39659dda3f78402;p=mastodonochrome.git Apply many uncontroversial style fixes from Clippy. 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. --- diff --git a/src/activity_stack.rs b/src/activity_stack.rs index 917ce6b..42a0135 100644 --- a/src/activity_stack.rs +++ b/src/activity_stack.rs @@ -153,14 +153,11 @@ impl ActivityStack { } pub fn overlay(&self) -> Option { - 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); diff --git a/src/client.rs b/src/client.rs index a223af8..b93ad45 100644 --- a/src/client.rs +++ b/src/client.rs @@ -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 {}", ¬.id))); } self.cache_notification(¬); @@ -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())) } } }?; diff --git a/src/coloured_string.rs b/src/coloured_string.rs index 574d055..885649f 100644 --- a/src/coloured_string.rs +++ b/src/coloured_string.rs @@ -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> 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> { diff --git a/src/editor.rs b/src/editor.rs index d357d96..f452a77 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -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 { 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 { 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))) } diff --git a/src/file.rs b/src/file.rs index 39e5a60..408eb93 100644 --- a/src/file.rs +++ b/src/file.rs @@ -63,7 +63,7 @@ impl FeedSource { impl FileDataSource for FeedSource { fn get(&self, client: &mut Client) -> (Vec, 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 { - 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 { - let not = client.notification_by_id(&id)?; + let not = client.notification_by_id(id)?; let st = ¬.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 { - let not = client.notification_by_id(&id)?; + let not = client.notification_by_id(id)?; Ok(NotificationLog::from_notification(¬, client)) } @@ -199,7 +199,7 @@ impl FileType for UserListFeedType { fn get_from_client(id: &str, client: &mut Client) -> Result { - 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 File { } } - if lines_rendered + 1 <= h { + if lines_rendered < h { Some(h - 1 - lines_rendered) } else { None @@ -418,12 +418,9 @@ impl File { 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 File { } 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 File { 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 File { 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 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, 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, 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 { 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 { - 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)) } diff --git a/src/html.rs b/src/html.rs index 30188b4..9e4debe 100644 --- a/src/html.rs +++ b/src/html.rs @@ -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>> { 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>> { 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>> { fn to_coloured_string(tl: &TaggedLine>) -> 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 diff --git a/src/login.rs b/src/login.rs index 7c771ef..867d802 100644 --- a/src/login.rs +++ b/src/login.rs @@ -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) @@ -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!"); diff --git a/src/main.rs b/src/main.rs index 7bee2fb..00df08d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,7 +47,7 @@ fn main() -> ExitCode { match main_inner() { Ok(_) => ExitCode::from(0), Err(e) => { - let _ = eprintln!("{}", e); + eprintln!("{}", e); ExitCode::from(1) } } diff --git a/src/posting.rs b/src/posting.rs index e720d83..cae1593 100644 --- a/src/posting.rs +++ b/src/posting.rs @@ -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(); diff --git a/src/scan_re.rs b/src/scan_re.rs index adc3844..2b16b14 100644 --- a/src/scan_re.rs +++ b/src/scan_re.rs @@ -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() + diff --git a/src/text.rs b/src/text.rs index e882753..a2bfd70 100644 --- a/src/text.rs +++ b/src/text.rs @@ -141,9 +141,10 @@ impl TextFragment for Vec { fn highlighted_id(&self, highlight: Option) -> Option { 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 ¬.status { - None => None, - Some(st) => Some(Html::new(&st.content).to_para()), - }; - let status_id = match ¬.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(¬.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 { 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:"))); } diff --git a/src/tui.rs b/src/tui.rs index 52c90a2..f8fe360 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -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?"))),