cargo fmt/clippy all the things + make them mandatory in CI
This commit is contained in:
@@ -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
|
||||
|
||||
30
src/album.rs
30
src/album.rs
@@ -16,7 +16,7 @@ pub struct Album {
|
||||
pub year: String,
|
||||
pub cover_url: Option<String>,
|
||||
pub url: String,
|
||||
pub tracks: Option<Vec<Track>>
|
||||
pub tracks: Option<Vec<Track>>,
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct Artist {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
pub albums: Option<Vec<Album>>
|
||||
pub albums: Option<Vec<Album>>,
|
||||
}
|
||||
|
||||
impl Artist {
|
||||
@@ -42,11 +42,12 @@ impl Artist {
|
||||
|
||||
fn tracks(&self) -> Option<Vec<&Track>> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,16 +55,16 @@ pub fn create_credentials(path: &Path) -> Result<RespotCredentials, String> {
|
||||
.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<RespotCredentials, String> {
|
||||
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?
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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<Page<SimplifiedAlbum>> {
|
||||
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) {
|
||||
|
||||
@@ -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<Spotify>,
|
||||
tracks: Arc<RwLock<Vec<Track>>>,
|
||||
query: String,
|
||||
) {
|
||||
fn search_track(spotify: Arc<Spotify>, tracks: Arc<RwLock<Vec<Track>>>, 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<Spotify>,
|
||||
albums: Arc<RwLock<Vec<Album>>>,
|
||||
query: String,
|
||||
) {
|
||||
fn search_album(spotify: Arc<Spotify>, albums: Arc<RwLock<Vec<Album>>>, 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<Spotify>,
|
||||
artists: Arc<RwLock<Vec<Artist>>>,
|
||||
query: String,
|
||||
) {
|
||||
fn search_artist(spotify: Arc<Spotify>, artists: Arc<RwLock<Vec<Artist>>>, 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;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<Tab>,
|
||||
ids: HashMap<String, usize>,
|
||||
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<S: Into<String>, 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user