diff --git a/.travis.yml b/.travis.yml index 6374286..1ad5f85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,3 +6,8 @@ matrix: fast_finish: true before_install: - sudo apt-get install -y libasound2-dev libdbus-1-dev +script: + - cargo update + - rustup component add clippy rustfmt + - cargo clippy --all-targets -- -D warnings + - cargo fmt --all -- --check diff --git a/src/album.rs b/src/album.rs index 347ec54..1bd0e0b 100644 --- a/src/album.rs +++ b/src/album.rs @@ -16,7 +16,7 @@ pub struct Album { pub year: String, pub cover_url: Option, pub url: String, - pub tracks: Option> + pub tracks: Option>, } impl Album { @@ -26,10 +26,12 @@ impl Album { } if let Some(fa) = spotify.full_album(&self.id) { - self.tracks = Some(fa.tracks.items - .iter() - .map(|st| Track::from_simplified_track(&st, &fa)) - .collect() + self.tracks = Some( + fa.tracks + .items + .iter() + .map(|st| Track::from_simplified_track(&st, &fa)) + .collect(), ); } } @@ -41,30 +43,32 @@ impl From<&SimplifiedAlbum> for Album { id: sa.id.clone(), title: sa.name.clone(), artists: sa.artists.iter().map(|sa| sa.name.clone()).collect(), - year: sa.release_date.split("-").next().unwrap().into(), + year: sa.release_date.split('-').next().unwrap().into(), cover_url: sa.images.get(0).map(|i| i.url.clone()), url: sa.uri.clone(), - tracks: None + tracks: None, } } } impl From<&FullAlbum> for Album { fn from(fa: &FullAlbum) -> Self { - let tracks = Some(fa.tracks.items - .iter() - .map(|st| Track::from_simplified_track(&st, &fa)) - .collect() + let tracks = Some( + fa.tracks + .items + .iter() + .map(|st| Track::from_simplified_track(&st, &fa)) + .collect(), ); Self { id: fa.id.clone(), title: fa.name.clone(), artists: fa.artists.iter().map(|sa| sa.name.clone()).collect(), - year: fa.release_date.split("-").next().unwrap().into(), + year: fa.release_date.split('-').next().unwrap().into(), cover_url: fa.images.get(0).map(|i| i.url.clone()), url: fa.uri.clone(), - tracks: tracks + tracks, } } } diff --git a/src/artist.rs b/src/artist.rs index b0794b2..f39685b 100644 --- a/src/artist.rs +++ b/src/artist.rs @@ -14,7 +14,7 @@ pub struct Artist { pub id: String, pub name: String, pub url: String, - pub albums: Option> + pub albums: Option>, } impl Artist { @@ -42,11 +42,12 @@ impl Artist { fn tracks(&self) -> Option> { if let Some(albums) = self.albums.as_ref() { - Some(albums - .iter() - .map(|a| a.tracks.as_ref().unwrap()) - .flatten() - .collect() + Some( + albums + .iter() + .map(|a| a.tracks.as_ref().unwrap()) + .flatten() + .collect(), ) } else { None @@ -60,7 +61,7 @@ impl From<&FullArtist> for Artist { id: fa.id.clone(), name: fa.name.clone(), url: fa.uri.clone(), - albums: None + albums: None, } } } diff --git a/src/authentication.rs b/src/authentication.rs index a56649d..0d64355 100644 --- a/src/authentication.rs +++ b/src/authentication.rs @@ -55,16 +55,16 @@ pub fn create_credentials(path: &Path) -> Result { .json() .expect("didn't parse"); // not a dialog to let people copy & paste the URL - let url_notice = TextView::new(format!("Browse to {}", urls.get("login_url").unwrap())); + let url_notice = TextView::new(format!("Browse to {}", &urls["login_url"])); let controls = Button::new("Quit", |s| s.quit()); let login_view = LinearLayout::new(cursive::direction::Orientation::Vertical) .child(url_notice) .child(controls); - let url = urls.get("login_url").unwrap(); + let url = &urls["login_url"]; webbrowser::open(url).ok(); - auth_poller(urls.get("credentials_url").unwrap(), &s.cb_sink()); + auth_poller(&urls["credentials_url"], &s.cb_sink()); s.pop_layer(); s.add_layer(login_view) }) @@ -76,7 +76,7 @@ pub fn create_credentials(path: &Path) -> Result { login_cursive .user_data() .cloned() - .unwrap_or(Err("Didn't obtain any credentials".to_string())) + .unwrap_or_else(|| Err("Didn't obtain any credentials".to_string())) } // TODO: better with futures? diff --git a/src/config.rs b/src/config.rs index 28ab330..b9db2fb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -88,11 +88,9 @@ pub fn load_or_generate_default< // Deserialize the content, optionally fall back to default if it fails let result = toml::from_str(&contents); - if default_on_parse_failure { - if let Err(_) = result { - let value = default(&path)?; - return write_content_helper(&path, value); - } + if default_on_parse_failure && result.is_err() { + let value = default(&path)?; + return write_content_helper(&path, value); } result.map_err(|e| format!("Unable to parse {}: {}", path.to_string_lossy(), e)) } diff --git a/src/spotify.rs b/src/spotify.rs index b8ff4d7..d0bdc58 100644 --- a/src/spotify.rs +++ b/src/spotify.rs @@ -16,7 +16,9 @@ use rspotify::spotify::client::Spotify as SpotifyAPI; use rspotify::spotify::model::album::{FullAlbum, SimplifiedAlbum}; use rspotify::spotify::model::page::Page; use rspotify::spotify::model::playlist::{PlaylistTrack, SimplifiedPlaylist}; -use rspotify::spotify::model::search::{SearchTracks, SearchAlbums, SearchArtists, SearchPlaylists}; +use rspotify::spotify::model::search::{ + SearchAlbums, SearchArtists, SearchPlaylists, SearchTracks, +}; use failure::Error; @@ -344,7 +346,10 @@ impl Spotify { // update token used by web api calls self.api.write().expect("can't writelock api").access_token = Some(token.access_token); - self.token_issued.write().unwrap().replace(SystemTime::now()); + self.token_issued + .write() + .unwrap() + .replace(SystemTime::now()); } /// retries once when rate limits are hit @@ -485,15 +490,11 @@ impl Spotify { &self, artist_id: &str, limit: u32, - offset: u32 + offset: u32, ) -> Option> { - self.api_with_retry(|api| api.artist_albums( - artist_id, - None, - None, - Some(limit), - Some(offset) - )) + self.api_with_retry(|api| { + api.artist_albums(artist_id, None, None, Some(limit), Some(offset)) + }) } pub fn load(&self, track: &Track) { diff --git a/src/ui/search.rs b/src/ui/search.rs index 032a115..33ab7db 100644 --- a/src/ui/search.rs +++ b/src/ui/search.rs @@ -54,10 +54,26 @@ impl SearchView { .with_id(EDIT_ID); let tabs = TabView::new() - .tab("tracks", "Tracks", ListView::new(results_tracks.clone(), queue.clone())) - .tab("albums", "Albums", ListView::new(results_albums.clone(), queue.clone())) - .tab("artists", "Artists", ListView::new(results_artists.clone(), queue.clone())) - .tab("playlists", "Playlists", ListView::new(results_playlists.clone(), queue.clone())); + .tab( + "tracks", + "Tracks", + ListView::new(results_tracks.clone(), queue.clone()), + ) + .tab( + "albums", + "Albums", + ListView::new(results_albums.clone(), queue.clone()), + ) + .tab( + "artists", + "Artists", + ListView::new(results_artists.clone(), queue.clone()), + ) + .tab( + "playlists", + "Playlists", + ListView::new(results_playlists.clone(), queue.clone()), + ); SearchView { results_tracks, @@ -79,52 +95,25 @@ impl SearchView { }); } - fn search_track( - spotify: Arc, - tracks: Arc>>, - query: String, - ) { + fn search_track(spotify: Arc, tracks: Arc>>, query: String) { if let Some(results) = spotify.search_track(&query, 50, 0) { - let t = results - .tracks - .items - .iter() - .map(|ft| ft.into()) - .collect(); + let t = results.tracks.items.iter().map(|ft| ft.into()).collect(); let mut r = tracks.write().unwrap(); *r = t; } } - fn search_album( - spotify: Arc, - albums: Arc>>, - query: String, - ) { + fn search_album(spotify: Arc, albums: Arc>>, query: String) { if let Some(results) = spotify.search_album(&query, 50, 0) { - let a = results - .albums - .items - .iter() - .map(|sa| sa.into()) - .collect(); + let a = results.albums.items.iter().map(|sa| sa.into()).collect(); let mut r = albums.write().unwrap(); *r = a; } } - fn search_artist( - spotify: Arc, - artists: Arc>>, - query: String, - ) { + fn search_artist(spotify: Arc, artists: Arc>>, query: String) { if let Some(results) = spotify.search_artist(&query, 50, 0) { - let a = results - .artists - .items - .iter() - .map(|fa| fa.into()) - .collect(); + let a = results.artists.items.iter().map(|fa| fa.into()).collect(); let mut r = artists.write().unwrap(); *r = a; } diff --git a/src/ui/statusbar.rs b/src/ui/statusbar.rs index 03fb82c..52b4ff9 100644 --- a/src/ui/statusbar.rs +++ b/src/ui/statusbar.rs @@ -40,7 +40,13 @@ impl View for StatusBar { ColorType::Palette(PaletteColor::Background), ); let style_bar_bg = ColorStyle::new( - ColorType::Color(*printer.theme.palette.custom("statusbar_progress_bg").unwrap()), + ColorType::Color( + *printer + .theme + .palette + .custom("statusbar_progress_bg") + .unwrap(), + ), ColorType::Palette(PaletteColor::Background), ); let style = ColorStyle::new( diff --git a/src/ui/tabview.rs b/src/ui/tabview.rs index 5eb2cab..3d71c0d 100644 --- a/src/ui/tabview.rs +++ b/src/ui/tabview.rs @@ -8,7 +8,7 @@ use cursive::{Cursive, Printer, Vec2}; use unicode_width::UnicodeWidthStr; use commands::CommandResult; -use traits::{ViewExt, IntoBoxedViewExt}; +use traits::{IntoBoxedViewExt, ViewExt}; pub struct Tab { title: String, @@ -18,7 +18,7 @@ pub struct Tab { pub struct TabView { tabs: Vec, ids: HashMap, - selected: usize + selected: usize, } impl TabView { @@ -26,14 +26,14 @@ impl TabView { Self { tabs: Vec::new(), ids: HashMap::new(), - selected: 0 + selected: 0, } } pub fn add_tab, V: IntoBoxedViewExt>(&mut self, id: S, title: S, view: V) { let tab = Tab { title: title.into(), - view: view.as_boxed_view_ext() + view: view.as_boxed_view_ext(), }; self.tabs.push(tab); self.ids.insert(id.into(), self.tabs.len() - 1); @@ -57,7 +57,7 @@ impl TabView { impl View for TabView { fn draw(&self, printer: &Printer<'_, '_>) { - if self.tabs.len() == 0 { + if self.tabs.is_empty() { return; }