From f7008e882c93d1a3a1a29fd40d9e1284326199bf Mon Sep 17 00:00:00 2001 From: MCorange Date: Sun, 22 Sep 2024 02:16:18 +0300 Subject: [PATCH] Clippy pedantic fixes --- assets/icon.png | Bin 0 -> 8561 bytes src/config/cli.rs | 2 + src/config/mod.rs | 102 +++++++++++------------- src/constants.rs | 14 ++-- src/downloader.rs | 22 +++--- src/logger.rs | 4 +- src/main.rs | 9 +-- src/manifest/mod.rs | 9 ++- src/manifest/song.rs | 25 +++--- src/prompt.rs | 109 +------------------------- src/ui/cli/add.rs | 14 ++-- src/ui/cli/mod.rs | 8 +- src/ui/gui/components/context_menu.rs | 12 +-- src/ui/gui/components/nav.rs | 3 +- src/ui/gui/components/song_list.rs | 12 ++- src/ui/gui/mod.rs | 18 ++--- src/ui/gui/windows/error.rs | 3 +- src/ui/gui/windows/import_playlist.rs | 4 +- src/ui/gui/windows/mod.rs | 10 +-- src/ui/gui/windows/song_edit.rs | 17 ++-- src/ui/gui/windows/song_new.rs | 30 +++---- src/util.rs | 10 +-- 22 files changed, 162 insertions(+), 275 deletions(-) create mode 100644 assets/icon.png diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a0a26e79d2fe4c9e3fc78a0ab2ebad764bad1005 GIT binary patch literal 8561 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 Result { + #[allow(clippy::field_reassign_with_default)] + pub fn parse() -> Result { let mut s = Self::default(); s.cli = cli::CliArgs::parse(); - crate::logger::init_logger(s.cli.debug); - s.cfg = Config::parse(&s.cli).await?; + crate::logger::init(s.cli.debug); + s.cfg = Config::parse(&s.cli)?; s.isatty = isatty(); Ok(s) } } impl Config { - pub async fn parse(cli: &CliArgs) -> Result { + pub fn parse(cli: &CliArgs) -> Result { if !cli.config.exists() { log::info!("Config doesnt exist"); - return Self::setup_config(&cli).await; + return Self::setup_config(cli); } let data = std::fs::read_to_string(&cli.config)?; @@ -59,63 +63,51 @@ impl Config { Ok(data) } - async fn setup_config(cli: &CliArgs) -> Result { + fn setup_config(cli: &CliArgs) -> Result { let mut s = Self::default(); let mut error = false; - match util::is_program_in_path("yt-dlp") { - Some(p) => { - s.ytdlp.path = p; - }, + if let Some(p) = util::is_program_in_path("yt-dlp") { + s.ytdlp.path = p; + } else { + error = true; + log::error!("could not find yt-dlp, please install it."); + log::info!(" - With winget (Windows only) (recommended):"); + log::info!(" - Most new windows versions have winget installed, if not, instructions here: https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget"); + log::info!(" - run `winget install yt-dlp`"); + log::info!(" - With chocolatey (Windows only):"); + log::info!(" - Make sure you have chocolatey installed - https://chocolatey.org/install"); + log::info!(" - run `choco install yt-dlp` as Admin"); + log::info!(" - With pip (from python) (Cross platform)"); + log::info!(" - Make sure you have python installed"); + log::info!(" - pip install yt-dlp"); + log::info!(" - Using your distro's package manager (Unix/BSD only) (Not recommended)"); + } - None => { + if let Some(p) = util::is_program_in_path("spotdl") { + s.spotdl.path = p; + } else { + let res = crate::prompt::yes_no("Spotdl is not installed but if you dont need to download music from spotify you dont need it, skip it?", None); + if res { + s.spotdl.path = PathBuf::from("UNUSED"); + } else { error = true; - log::error!("could not find yt-dlp, please install it."); - log::info!(" - With winget (Windows only) (recommended):"); - log::info!(" - Most new windows versions have winget installed, if not, instructions here: https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget"); - log::info!(" - run `winget install yt-dlp`"); - log::info!(" - With chocolatey (Windows only):"); - log::info!(" - Make sure you have chocolatey installed - https://chocolatey.org/install"); - log::info!(" - run `choco install yt-dlp` as Admin"); - log::info!(" - With pip (from python) (Cross platform)"); - log::info!(" - Make sure you have python installed"); - log::info!(" - pip install yt-dlp"); - log::info!(" - Using your distro's package manager (Unix/BSD only) (Not recommended)") + log::error!("could not find spotdl, please install it. "); + log::info!(" - With pip (from python) (Cross platform) (recommended)"); + log::info!(" - Make sure you have python installed - https://www.python.org/downloads/"); + log::info!(" - pip install spotdl"); } } - match util::is_program_in_path("spotdl") { - Some(p) => { - s.spotdl.path = p; - }, - - None => { - let res = crate::prompt::prompt_bool("Spotdl is not installed but if you dont need to download music from spotify you dont need it, skip it?", None); - if res { - s.spotdl.path = PathBuf::from("UNUSED"); - } else { - error = true; - log::error!("could not find spotdl, please install it. "); - log::info!(" - With pip (from python) (Cross platform) (recommended)"); - log::info!(" - Make sure you have python installed - https://www.python.org/downloads/"); - log::info!(" - pip install spotdl"); - } - } - } - - match util::is_program_in_path("ffmpeg") { - Some(_) => (), - - None => { - error = true; - log::error!("could not find ffmpeg, please install it."); - log::info!(" - With winget (Windows only) (recommended):"); - log::info!(" - Most new windows versions have winget installed, if not, instructions here: https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget"); - log::info!(" - run `winget install --id=Gyan.FFmpeg -e`"); - log::info!(" - With chocolatey (Windows only):"); - log::info!(" - Make sure you have chocolatey installed - https://chocolatey.org/install"); - log::info!(" - run `choco install ffmpeg` as Admin"); - } + if util::is_program_in_path("ffmpeg").is_none() { + error = true; + log::error!("could not find ffmpeg, please install it."); + log::info!(" - With winget (Windows only) (recommended):"); + log::info!(" - Most new windows versions have winget installed, if not, instructions here: https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget"); + log::info!(" - run `winget install --id=Gyan.FFmpeg -e`"); + log::info!(" - With chocolatey (Windows only):"); + log::info!(" - Make sure you have chocolatey installed - https://chocolatey.org/install"); + log::info!(" - run `choco install ffmpeg` as Admin"); } if !error { diff --git a/src/constants.rs b/src/constants.rs index 6b0f8de..c9e0964 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,15 +1,15 @@ #[cfg(target_family="windows")] -mod constants { - pub const PATH_VAR_SEP: &'static str = ";"; - pub const EXEC_EXT: &'static str = "exe"; +mod _m { + pub const PATH_VAR_SEP: &str = ";"; + pub const EXEC_EXT: &str = "exe"; } #[cfg(target_family="unix")] -mod constants { - pub const PATH_VAR_SEP: &'static str = ":"; - pub const EXEC_EXT: &'static str = ""; +mod _m { + pub const PATH_VAR_SEP: &str = ":"; + pub const EXEC_EXT: &str = ""; } -pub use constants::*; \ No newline at end of file +pub use _m::*; diff --git a/src/downloader.rs b/src/downloader.rs index 30dfd6a..c514250 100644 --- a/src/downloader.rs +++ b/src/downloader.rs @@ -40,8 +40,8 @@ impl Downloader { self.nb_cache.len() + crate::process_manager::proc_count() } - pub fn download_song_nb(&mut self, cfg: &ConfigWrapper, pname: &String, sname: &String, song: &Song, format: &Format) -> anyhow::Result<()> { - self.nb_cache.push((pname.clone(), sname.clone(), song.clone(), format.clone())); + pub fn download_song_nb(&mut self, cfg: &ConfigWrapper, pname: &str, sname: &str, song: &Song, format: &Format) -> anyhow::Result<()> { + self.nb_cache.push((pname.to_string(), sname.to_string(), song.clone(), format.clone())); self.nb_initial_song_count += 1; self.download_all_nb_poll(cfg)?; Ok(()) @@ -76,12 +76,12 @@ impl Downloader { - pub async fn download_all(&mut self, manifest: &Manifest, cfg: &ConfigWrapper) -> anyhow::Result { + pub fn download_all(&mut self, manifest: &Manifest, cfg: &ConfigWrapper) -> anyhow::Result { let format = manifest.get_format(); for (name, playlist) in manifest.get_playlists() { for (song_name, song) in playlist.get_songs() { - self.download_song(cfg, song_name, song, &name, format)?; + self.download_song(cfg, song_name, song, name, format)?; self.count += crate::process_manager::wait_for_procs_untill(10)?; } } @@ -90,7 +90,7 @@ impl Downloader { } #[allow(dead_code)] - pub fn download_playlist(&mut self, cfg: &ConfigWrapper, url: &String, pname: &String, format: &Format) -> anyhow::Result { + pub fn download_playlist(&mut self, cfg: &ConfigWrapper, url: &str, pname: &str, format: &Format) -> anyhow::Result { self.download_playlist_nb(cfg, url, pname, format)?; let mut count = 0; while let Some(c) = self.download_all_nb_poll(cfg)? { @@ -99,14 +99,14 @@ impl Downloader { Ok(count) } - pub fn download_playlist_nb(&mut self, cfg: &ConfigWrapper, url: &String, pname: &String, format: &Format) -> anyhow::Result> { + pub fn download_playlist_nb(&mut self, cfg: &ConfigWrapper, url: &str, pname: &str, format: &Format) -> anyhow::Result> { log::warn!("This automatically assumes its a youtube link as it is currently the only supported playlist source"); let mut cmd = tokio::process::Command::new(&cfg.cfg.ytdlp.path); cmd.args([ "--flat-playlist", "--simulate", "-O", "%(url)s|%(title)s", - url.as_str() + url ]); cmd .stderr(Stdio::null()) @@ -119,11 +119,11 @@ impl Downloader { let out = futures::executor::block_on(ftr)?.stdout; let out = String::from_utf8(out)?; for line in out.lines() { - let mut split_text = line.split("|").collect::>(); + let mut split_text = line.split('|').collect::>(); let url = split_text.swap_remove(0).to_string(); let sname = split_text.join("|"); let song = Song::from_url_str(url)?.set_type(SongType::Youtube).clone(); - self.nb_cache.push((pname.clone(), sname.clone(), song.clone(), format.clone())); + self.nb_cache.push((pname.to_string(), sname.clone(), song.clone(), format.clone())); ret.insert(sname, song.clone()); } self.nb_initial_song_count += out.lines().count(); @@ -131,7 +131,7 @@ impl Downloader { Ok(ret) } - pub fn download_song(&mut self, cfg: &ConfigWrapper, name: &String, song: &Song, playlist: &String, format: &Format) -> anyhow::Result<()> { + pub fn download_song(&self, cfg: &ConfigWrapper, name: &String, song: &Song, playlist: &String, format: &Format) -> anyhow::Result<()> { let dl_dir = format!("{}/{playlist}", cfg.cli.output); let dl_file = format!("{dl_dir}/{}.{}", name, &format); log::debug!("Checking: {dl_file}"); @@ -168,7 +168,7 @@ impl Downloader { ]); cmd } - url => { + url @ SongType::Soundcloud => { log::error!("Unknown or unsupported hostname '{:?}'", url); return Ok(()); } diff --git a/src/logger.rs b/src/logger.rs index 82f7ebb..f89207a 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -1,7 +1,7 @@ use log::LevelFilter; -pub fn init_logger(debug: bool) { +pub fn init(debug: bool) { let level = if debug { LevelFilter::Debug } else { @@ -11,4 +11,4 @@ pub fn init_logger(debug: bool) { .format_timestamp(None) .filter_level(level) .init(); -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index e2f71d0..f66d75c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,15 +8,14 @@ mod manifest; mod logger; mod downloader; mod util; -mod prompt; mod config; mod constants; mod process_manager; mod ui; +mod prompt; -#[tokio::main] -async fn main() { - let Ok(cfg) = ConfigWrapper::parse().await else { +fn main() { + let Ok(cfg) = ConfigWrapper::parse() else { return; }; @@ -29,5 +28,5 @@ async fn main() { }; - let _ = ui::cli::command_run(&cfg, &mut manifest).await; + let _ = ui::cli::command_run(&cfg, &mut manifest); } diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index dbe0d99..1c9e015 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -2,6 +2,7 @@ pub mod song; pub mod playlist; +use playlist::Playlist; use song::Song; use std::{collections::HashMap, fmt::{Debug, Display}, path::PathBuf}; @@ -10,7 +11,7 @@ use anyhow::{bail, Result}; use serde::{Deserialize, Serialize}; -const DEFAULT_MANIFEST: &'static str = include_str!("../../manifest.default.json"); +const DEFAULT_MANIFEST: &str = include_str!("../../manifest.default.json"); @@ -51,7 +52,7 @@ impl Manifest { self.get_playlist_mut(playlist_name)?.get_song_mut(name) } pub fn add_playlist(&mut self, playlist_name: String) { - self.playlists.insert(playlist_name, Default::default()); + self.playlists.insert(playlist_name, Playlist::default()); } pub fn get_playlist(&self, playlist_name: &String) -> Option<&playlist::Playlist> { self.playlists.get(playlist_name) @@ -67,7 +68,7 @@ impl Manifest { } pub fn get_song_count(&self) -> usize { let mut count = 0; - for (_, v) in &self.playlists { + for v in self.playlists.values() { count += v.len(); } count @@ -98,7 +99,7 @@ impl Manifest { let mut s = Self::default(); log::debug!("Path: {p:?}"); - s.path = p.clone(); + s.path.clone_from(p); s.load(Some(p))?; Ok(s) } diff --git a/src/manifest/song.rs b/src/manifest/song.rs index eba75ff..7d7960a 100644 --- a/src/manifest/song.rs +++ b/src/manifest/song.rs @@ -1,9 +1,9 @@ -use std::str::FromStr; +use std::{fmt::Display, str::FromStr}; use anyhow::{bail, Result}; use serde::{Deserialize, Serialize}; - +#[allow(clippy::pedantic)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Default)] pub enum SongType { #[default] @@ -12,14 +12,14 @@ pub enum SongType { Soundcloud, } -impl ToString for SongType { - fn to_string(&self) -> String { - let s = match self { - SongType::Youtube => "Youtube", - SongType::Spotify => "Spotify", - SongType::Soundcloud => "Soundcloud", - }; - String::from(s) +impl Display for SongType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Soundcloud => write!(f, "SoundCloud")?, + Self::Spotify => write!(f, "Spotify")?, + Self::Youtube => write!(f, "YouTube")?, + } + Ok(()) } } @@ -31,8 +31,9 @@ pub struct Song { #[allow(dead_code)] impl Song { - pub fn from_url_str(url: String) -> Result { - Self::from_url(url::Url::from_str(url.as_str())?) + #[allow(clippy::needless_pass_by_value)] + pub fn from_url_str(url: S) -> Result { + Self::from_url(url::Url::from_str(&url.to_string())?) } pub fn from_url(url: url::Url) -> Result { Ok(Self { diff --git a/src/prompt.rs b/src/prompt.rs index de9d891..daa059c 100644 --- a/src/prompt.rs +++ b/src/prompt.rs @@ -1,108 +1,7 @@ -use std::{collections::HashMap, io::Write}; +use std::io::Write; -//pub(crate) fn simple_prompt(p: &str) -> String { -// -// print!("{c}prompt{r}: {p} > ", -// c=anstyle::AnsiColor::Cyan.render_fg(), -// r=anstyle::Reset.render() -// ); -// -// // I dont care if it fails -// let _ = std::io::stdout().flush(); -// -// let mut buf = String::new(); -// let _ = std::io::stdin().read_line(&mut buf); -// -// buf.trim().to_string() -//} - -#[allow(dead_code)] -pub(crate) fn prompt_with_list(p: &str, options: &[&str]) -> usize { - println!("{c}prompt{r}: {p}", - c=anstyle::AnsiColor::Cyan.render_fg(), - r=anstyle::Reset.render() - ); - - for (i, op) in options.iter().enumerate() { - println!(" - {}: {}", i, op); - } - - print!("> "); - // I dont care if it fails - let _ = std::io::stdout().flush(); - - let mut buf = String::new(); - let _ = std::io::stdin().read_line(&mut buf); - - if let Ok(num) = buf.parse::() { - if num <= options.len() { - return num; - } else { - return prompt_with_list(p, options); - } - } else { - return prompt_with_list(p, options); - } -} - -// pub(crate) fn prompt_with_list_or_str(p: &str, options: &[String]) -> String { -// println!("{c}prompt{r}: {p} (select with number or input text)", -// c=anstyle::AnsiColor::Cyan.render_fg(), -// r=anstyle::Reset.render() -// ); -// -// for (i, op) in options.iter().enumerate() { -// println!(" - {}: {}", i, op); -// } -// -// print!("> "); -// // I dont care if it fails -// let _ = std::io::stdout().flush(); -// -// let mut buf = String::new(); -// let _ = std::io::stdin().read_line(&mut buf); -// -// if let Ok(num) = buf.trim().parse::() { -// if let Some(g) = options.get(num) { -// return g.clone(); -// } else { -// return prompt_with_list_or_str(p, options); -// } -// } else { -// return buf.trim().to_string(); -// } -// } - - -#[allow(dead_code)] -pub(crate) fn prompt_with_map(p: &str, options: HashMap<&str, &str>) -> String { - println!("{c}prompt{r}: {p}", - c=anstyle::AnsiColor::Cyan.render_fg(), - r=anstyle::Reset.render() - ); - - let mut keys = Vec::new(); - - for (k, v) in &options { - println!(" - {}: {}", k, v); - keys.push(k.trim().to_lowercase()) - } - - print!("> "); - - // I dont care if it fails - let _ = std::io::stdout().flush(); - - let mut buf = String::new(); - let _ = std::io::stdin().read_line(&mut buf); - if !keys.contains(&buf.trim().to_lowercase()) { - return prompt_with_map(p, options); - } - buf.trim().to_string() -} - -pub fn prompt_bool(p: &str, default: Option) -> bool { +pub fn yes_no(p: &str, default: Option) -> bool { if default == Some(true) { println!("{c}prompt{r}: {p} (Y/n)", c=anstyle::AnsiColor::Cyan.render_fg(), @@ -132,7 +31,7 @@ pub fn prompt_bool(p: &str, default: Option) -> bool { Some(true) => return true, Some(false) => return false, None => { - return prompt_bool(p, default); + return yes_no(p, default); } } } @@ -142,7 +41,7 @@ pub fn prompt_bool(p: &str, default: Option) -> bool { "n" => false, c => { log::error!("'{c}' is invalid, type y (yes) or n (no)"); - return prompt_bool(p, default); + yes_no(p, default) } } } diff --git a/src/ui/cli/add.rs b/src/ui/cli/add.rs index 4ee9fb5..4250b99 100644 --- a/src/ui/cli/add.rs +++ b/src/ui/cli/add.rs @@ -6,34 +6,34 @@ use crate::{config::ConfigWrapper, downloader::Downloader, manifest::{song::Song -pub async fn add(cfg: &ConfigWrapper, manifest: &mut Manifest, downloader: &mut Downloader, url: &String, name: &String, playlist: &String) -> anyhow::Result<()> { +pub fn song(cfg: &ConfigWrapper, manifest: &mut Manifest, downloader: &mut Downloader, url: &str, name: &String, playlist: &String) -> anyhow::Result<()> { - let mut playlists = manifest.get_playlists().keys().map(|f| f.clone()).collect::>(); + let mut playlists = manifest.get_playlists().keys().cloned().collect::>(); playlists.sort(); - if !is_supported_host(url::Url::from_str(&url)?) { + if !is_supported_host(&url::Url::from_str(url)?) { log::error!("Invalid or unsupported host name"); return Ok(()); } - let song = Song::from_url_str(url.clone())?; + let song = Song::from_url_str(url.to_string())?; manifest.add_song(playlist, name.clone(), song.clone()); manifest.save(None)?; - let should_download = crate::prompt::prompt_bool("Download song now?", Some(false)); + let should_download = crate::prompt::yes_no("Download song now?", Some(false)); if should_download { - downloader.download_song(cfg, &name, &song, &playlist, manifest.get_format())?; + downloader.download_song(cfg, name, &song, playlist, manifest.get_format())?; crate::process_manager::wait_for_procs_untill(0)?; } Ok(()) } -pub async fn add_playlist(cfg: &ConfigWrapper, manifest: &mut Manifest, downloader: &mut Downloader, url: &String, name: &String) -> anyhow::Result<()> { +pub fn playlist(cfg: &ConfigWrapper, manifest: &mut Manifest, downloader: &mut Downloader, url: &str, name: &String) -> anyhow::Result<()> { let songs = downloader.download_playlist_nb(cfg, url, name, manifest.get_format())?; if manifest.get_playlist(name).is_some() { diff --git a/src/ui/cli/mod.rs b/src/ui/cli/mod.rs index 6c975ad..cf8f53f 100644 --- a/src/ui/cli/mod.rs +++ b/src/ui/cli/mod.rs @@ -4,14 +4,14 @@ use crate::{config::{cli::CliCommand, ConfigWrapper}, downloader::Downloader, ma -pub async fn command_run(cfg: &ConfigWrapper, manifest: &mut Manifest) -> anyhow::Result<()> { +pub fn command_run(cfg: &ConfigWrapper, manifest: &mut Manifest) -> anyhow::Result<()> { log::info!("Is in term: {}", cfg.isatty); //std::fs::write("./isatty", format!("{}\n", cfg.isatty))?; let mut downloader = Downloader::new(); match (&cfg.cli.command, cfg.isatty) { (None | Some(CliCommand::Download), true) => { - match downloader.download_all(manifest, &cfg).await { + match downloader.download_all(manifest, cfg) { Ok(count) => log::info!("Downloaded {count} songs"), Err(e) => { log::error!("Failed to download songs: {e}"); @@ -23,12 +23,12 @@ pub async fn command_run(cfg: &ConfigWrapper, manifest: &mut Manifest) -> anyhow match c { CliCommand::Download => unreachable!(), CliCommand::AddPlaylist { url, name } => { - if let Err(e) = add::add_playlist(cfg, manifest, &mut downloader, url, name).await { + if let Err(e) = add::playlist(cfg, manifest, &mut downloader, url, name) { log::error!("Failed to run 'add-playlist' commmand: {e}"); } } CliCommand::Add { url, name, playlist } => { - if let Err(e) = add::add(cfg, manifest, &mut downloader, url, name, playlist).await { + if let Err(e) = add::song(cfg, manifest, &mut downloader, url, name, playlist) { log::error!("Failed to run 'add' command: {e}"); } } diff --git a/src/ui/gui/components/context_menu.rs b/src/ui/gui/components/context_menu.rs index abea285..27deec1 100644 --- a/src/ui/gui/components/context_menu.rs +++ b/src/ui/gui/components/context_menu.rs @@ -11,7 +11,7 @@ impl /* ComponentUi for */ ContextMenu { let w = gui.windows.get_window::(WindowIndex::SongEdit); w.set_active_song(pname, sname, song.get_url_str()); gui.windows.open(WindowIndex::SongEdit, true); - ui.close_menu() + ui.close_menu(); } if ui.button("Download").clicked() { @@ -19,7 +19,7 @@ impl /* ComponentUi for */ ContextMenu { log::error!("{e}"); gui.throw_error(format!("Failed to download song {sname}: {e}")); } - ui.close_menu() + ui.close_menu(); } if ui.button("Open Source").clicked() { @@ -27,18 +27,18 @@ impl /* ComponentUi for */ ContextMenu { log::error!("{e}"); gui.throw_error(format!("Failed to open song source: {e}")); } - ui.close_menu() + ui.close_menu(); } if ui.button("Play").clicked() { let p = crate::util::get_song_path(pname, sname, gui.manifest.get_format()); if !p.exists() { - gui.throw_error(format!("Song does not exist on disk")); + gui.throw_error("Song does not exist on disk".to_string()); } else if let Err(e) = open::that(p) { log::error!("{e}"); gui.throw_error(format!("Failed to play song: {e}")); } - ui.close_menu() + ui.close_menu(); } if ui.button("Delete from disk").clicked() { let p = crate::util::get_song_path(pname, sname, gui.manifest.get_format()); @@ -51,7 +51,7 @@ impl /* ComponentUi for */ ContextMenu { } if ui.button(RichText::new("Delete").color(Color32::RED)).clicked() { gui.throw_error("TODO"); - ui.close_menu() + ui.close_menu(); } } } diff --git a/src/ui/gui/components/nav.rs b/src/ui/gui/components/nav.rs index 88d46a6..4480437 100644 --- a/src/ui/gui/components/nav.rs +++ b/src/ui/gui/components/nav.rs @@ -3,8 +3,9 @@ use crate::ui::gui::{windows::WindowIndex, Gui}; use super::Component; - +#[allow(clippy::pedantic)] pub struct NavBar; +#[warn(clippy::pedantic)] impl Component for NavBar { fn ui(gui: &mut Gui, ctx: &egui::Context) { diff --git a/src/ui/gui/components/song_list.rs b/src/ui/gui/components/song_list.rs index 5b62b29..98c3a61 100644 --- a/src/ui/gui/components/song_list.rs +++ b/src/ui/gui/components/song_list.rs @@ -1,4 +1,4 @@ -use egui::{Color32, RichText}; +use egui::Color32; use egui_extras::{Column, TableBuilder}; use crate::manifest::song::SongType; @@ -60,7 +60,7 @@ impl ComponentUi for SongList { let mut songs = Vec::new(); for (pname, p) in playlists { for (sname, s) in p { - songs.push((pname.clone(), sname, s)) + songs.push((pname.clone(), sname, s)); } } songs @@ -91,10 +91,8 @@ impl ComponentUi for SongList { if !s.get_url_str().contains(&filter_clean) { continue; } - } else if !filter_clean.is_empty() { - if !sname.to_lowercase().contains(&filter_clean) { - continue; - } + } else if !filter_clean.is_empty() && !sname.to_lowercase().contains(&filter_clean) { + continue; } body.row(18.0, |mut row| { @@ -121,7 +119,7 @@ impl ComponentUi for SongList { row.response() .context_menu(|ui| ContextMenu::ui(gui, ui, &pname, &sname, &s)); - }) + }); } }); }); diff --git a/src/ui/gui/mod.rs b/src/ui/gui/mod.rs index 1ef225c..5ac0e28 100644 --- a/src/ui/gui/mod.rs +++ b/src/ui/gui/mod.rs @@ -31,12 +31,10 @@ impl Gui { let native_options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() .with_inner_size([400.0, 300.0]) - .with_min_inner_size([300.0, 220.0]), - // .with_icon( - // // NOTE: Adding an icon is optional - // eframe::icon_data::from_png_bytes(&include_bytes!("../assets/icon-256.png")[..]) - // .expect("Failed to load icon"), - // ), + .with_min_inner_size([300.0, 220.0]) + .with_icon( + eframe::icon_data::from_png_bytes(&include_bytes!("../../../assets/icon.png")[..])?, + ), ..Default::default() }; @@ -50,9 +48,11 @@ impl Gui { Ok(()) } - pub fn throw_error(&mut self, text: impl ToString) { + + #[allow(clippy::pedantic)] + pub fn throw_error(&mut self, text: S) { let w = self.windows.get_window::(WindowIndex::Error); - w.set_error_message(text); + w.set_error_message(&text); self.windows.open(WindowIndex::Error, true); } } @@ -66,7 +66,7 @@ impl eframe::App for Gui { downloader: self.downloader.clone(), manifest: self.manifest.clone(), }; - self.windows.ui(&mut state, ctx).unwrap(); + self.windows.ui(&mut state, ctx); self.cfg = state.cfg; self.downloader = state.downloader; self.manifest = state.manifest; diff --git a/src/ui/gui/windows/error.rs b/src/ui/gui/windows/error.rs index 5c7d166..a10dd1c 100644 --- a/src/ui/gui/windows/error.rs +++ b/src/ui/gui/windows/error.rs @@ -3,6 +3,7 @@ use egui::{Color32, Label, RichText}; use super::{State, Window}; +#[allow(clippy::pedantic)] #[derive(Debug, Default)] pub struct GuiError { text: String, @@ -26,7 +27,7 @@ impl Window for GuiError { } impl GuiError { - pub fn set_error_message(&mut self, text: S) { + pub fn set_error_message(&mut self, text: &S) { self.text = text.to_string(); } } diff --git a/src/ui/gui/windows/import_playlist.rs b/src/ui/gui/windows/import_playlist.rs index 7170b4e..a7a373f 100644 --- a/src/ui/gui/windows/import_playlist.rs +++ b/src/ui/gui/windows/import_playlist.rs @@ -1,7 +1,7 @@ use super::{State, Window}; - +#[allow(clippy::pedantic)] #[derive(Debug, Default)] pub struct GuiImportPlaylist { ed_name: String, @@ -41,7 +41,7 @@ impl Window for GuiImportPlaylist { log::error!("Playlist {name} already exists"); } - let songs = state.downloader.download_playlist_nb(&state.cfg, &url, &name, &state.manifest.get_format()).unwrap(); + let songs = state.downloader.download_playlist_nb(&state.cfg, &url, &name, state.manifest.get_format()).unwrap(); state.manifest.add_playlist(name.clone()); let playlist = state.manifest.get_playlist_mut(&name).expect("Unreachable"); diff --git a/src/ui/gui/windows/mod.rs b/src/ui/gui/windows/mod.rs index a6cbcd3..5eac44c 100644 --- a/src/ui/gui/windows/mod.rs +++ b/src/ui/gui/windows/mod.rs @@ -45,17 +45,17 @@ impl WindowManager { } #[allow(dead_code)] - pub fn is_open(&self, id: &WindowIndex) -> bool { - *self.opened.get(id).unwrap() + pub fn is_open(&self, id: WindowIndex) -> bool { + *self.opened.get(&id).unwrap() } pub fn open(&mut self, id: WindowIndex, open: bool) { self.opened.insert(id, open); } - pub fn ui(&mut self, state: &mut State, ctx: &egui::Context) -> anyhow::Result<()> { + pub fn ui(&mut self, state: &mut State, ctx: &egui::Context) { for (id, window) in &mut self.windows { - if !self.opened.contains_key(&id) { + if !self.opened.contains_key(id) { self.opened.insert(*id, false); } let open = self.opened.get_mut(id).unwrap(); @@ -63,8 +63,6 @@ impl WindowManager { log::error!("Window {id:?} errored: {e}"); } } - - Ok(()) } pub fn get_window(&mut self, id: WindowIndex) -> &mut Box { diff --git a/src/ui/gui/windows/song_edit.rs b/src/ui/gui/windows/song_edit.rs index 9fa6a48..39e0182 100644 --- a/src/ui/gui/windows/song_edit.rs +++ b/src/ui/gui/windows/song_edit.rs @@ -1,6 +1,5 @@ -use anyhow::{Result, bail}; +use anyhow::bail; use egui::Color32; -use crate::ui::gui::Gui; use super::{State, Window}; @@ -44,7 +43,7 @@ impl Window for GuiSongEditor { ui.horizontal(|ui| { ui.label("Type: "); - ui.label(&song.get_type().to_string()); + ui.label(song.get_type().to_string()); }); ui.horizontal(|ui| { @@ -67,7 +66,7 @@ impl Window for GuiSongEditor { bail!("Failed to get song (2)"); }; - *song.get_url_str_mut() = self.ed_url.clone(); + song.get_url_str_mut().clone_from(&self.ed_url); } let Some(playlist) = state.manifest.get_playlist_mut(&playlist) else { @@ -86,10 +85,10 @@ impl Window for GuiSongEditor { } impl GuiSongEditor { - pub fn set_active_song(&mut self, pname: &String, sname: &String, url: &String) { - self.song.0 = pname.clone(); - self.song.1 = sname.clone(); - self.ed_name = sname.clone(); - self.ed_url = url.clone(); + pub fn set_active_song(&mut self, pname: &str, sname: &str, url: &str) { + self.song.0 = pname.to_string(); + self.song.1 = sname.to_string(); + self.ed_name = sname.to_string(); + self.ed_url = url.to_string(); } } diff --git a/src/ui/gui/windows/song_new.rs b/src/ui/gui/windows/song_new.rs index 8728bfc..8c3ddb6 100644 --- a/src/ui/gui/windows/song_new.rs +++ b/src/ui/gui/windows/song_new.rs @@ -3,10 +3,10 @@ use super::{State, Window}; #[derive(Debug, Default)] pub struct GuiNewSong { - ed_type: SongType, - ed_name: String, - ed_playlist: Option, - ed_url: String, + typ: SongType, + name: String, + playlist: Option, + url: String, } impl Window for GuiNewSong { @@ -18,33 +18,33 @@ impl Window for GuiNewSong { ui.horizontal(|ui| { ui.label("Type: "); egui::ComboBox::from_id_source("new_song_window_type") - .selected_text(format!("{:?}", self.ed_type)) + .selected_text(format!("{:?}", self.typ)) .show_ui(ui, |ui| { - ui.selectable_value(&mut self.ed_type, SongType::Youtube, "Youtube"); - ui.selectable_value(&mut self.ed_type, SongType::Spotify, "Spotify"); - ui.selectable_value(&mut self.ed_type, SongType::Soundcloud, "Soundcloud"); + ui.selectable_value(&mut self.typ, SongType::Youtube, "Youtube"); + ui.selectable_value(&mut self.typ, SongType::Spotify, "Spotify"); + ui.selectable_value(&mut self.typ, SongType::Soundcloud, "Soundcloud"); } ); }); ui.horizontal(|ui| { ui.label("Name: "); - ui.text_edit_singleline(&mut self.ed_name); + ui.text_edit_singleline(&mut self.name); }); ui.horizontal(|ui| { ui.label("Playlist: "); egui::ComboBox::from_id_source("new_song_window_playlist") - .selected_text(format!("{}", self.ed_playlist.clone().unwrap_or("".to_string()))) + .selected_text(self.playlist.clone().unwrap_or_default()) .show_ui(ui, |ui| { for p in state.manifest.get_playlists().keys() { - ui.selectable_value(&mut self.ed_playlist, Option::Some(p.clone()), p.as_str()); + ui.selectable_value(&mut self.playlist, Option::Some(p.clone()), p.as_str()); } } ); }); ui.horizontal(|ui| { ui.label("Url: "); - ui.text_edit_singleline(&mut self.ed_url); + ui.text_edit_singleline(&mut self.url); }); if ui.button("Save").clicked() { @@ -53,13 +53,13 @@ impl Window for GuiNewSong { }); if save { - let Some(playlist) = state.manifest.get_playlist_mut(&self.ed_playlist.clone().unwrap()) else { + let Some(playlist) = state.manifest.get_playlist_mut(&self.playlist.clone().unwrap()) else { panic!("couldnt find playlist from a preset playlist list????????????"); }; playlist.add_song( - self.ed_name.clone(), - Song::from_url_str(self.ed_url.clone()).unwrap().set_type(self.ed_type.clone()).clone() + self.name.clone(), + Song::from_url_str(self.url.clone()).unwrap().set_type(self.typ.clone()).clone() ); diff --git a/src/util.rs b/src/util.rs index 40c246b..d54884d 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,16 +2,12 @@ use std::{any::Any, path::PathBuf}; use crate::{constants, manifest::Format}; -pub(crate) fn is_supported_host(url: url::Url) -> bool { +pub(crate) fn is_supported_host(url: &url::Url) -> bool { let host = url.host_str(); if host.is_none() { return false; } - match host.unwrap() { - "youtube.com" | "youtu.be" | - "open.spotify.com" => true, - _ => false - } + matches!(host.unwrap(), "youtube.com" | "youtu.be" | "open.spotify.com") } pub(crate) fn is_program_in_path(program: &str) -> Option { @@ -66,7 +62,7 @@ pub fn get_song_path/*>*/(/*basepath: Option

,*/ pname: &S path = std::env::current_dir().unwrap_or(PathBuf::new()); } } else {*/ - let mut path = std::env::current_dir().unwrap_or(PathBuf::new()); + let mut path = std::env::current_dir().unwrap_or_default(); //} // TODO: Get this from cfg path.push("out");