diff --git a/src/cmus/mod.rs b/src/cmus/mod.rs index afd5bef..b51ebcb 100644 --- a/src/cmus/mod.rs +++ b/src/cmus/mod.rs @@ -136,11 +136,32 @@ impl Track { /// Make a status request to cmus. /// And collect the output, and parse it into a `Track`. /// If the cmus is not running, or the socket is not available, this function will return an error. -pub fn get_track(cmus_remote_bin: &[&str], socket_addr: Option<&str>, socket_pass: Option<&str>) -> Result { - let mut command = std::process::Command::new(cmus_remote_bin[0]); +#[inline] +pub fn get_track(query_command: &mut std::process::Command) -> Result { + // Just run the command, and collect the output. + let output = query_command.output().map_err(|e| CmusError::CmusRunningError(e.to_string()))?; - for arg in cmus_remote_bin.iter().skip(1) { - command.arg(arg); + if !output.status.success() { + return Err(CmusError::CmusRunningError(String::from_utf8(output.stderr) + .map_err(|e| CmusError::UnknownError(e.to_string()))?)); + } + + let output = String::from_utf8(output.stdout).map_err(|e| CmusError::UnknownError(e.to_string()))?; + + Track::from_str(&output).map_err(|e| CmusError::UnknownError(e.to_string())) +} + +/// Build the query command. +/// This function it should call only one time entire the program life time, So it makes sense to make it inline. +/// This function will return a `std::process::Command` that can be used to query cmus, you should store it in a variable :). +#[inline(always)] +pub fn build_query_command(cmus_remote_bin: &str, socket_addr: &Option, socket_pass: &Option) -> std::process::Command { + let cmd_arr = cmus_remote_bin.split_whitespace().collect::>(); + let mut command = std::process::Command::new(cmd_arr[0]); + + // If there are more than 1 slice, then add the rest of the slices as arguments. + if cmd_arr.len() > 1 { + command.args(&cmd_arr[1..]); } if let Some(socket_addr) = socket_addr { @@ -153,16 +174,7 @@ pub fn get_track(cmus_remote_bin: &[&str], socket_addr: Option<&str>, socket_pas command.arg("-Q"); - let output = command.output().map_err(|e| CmusError::CmusRunningError(e.to_string()))?; - - if !output.status.success() { - return Err(CmusError::CmusRunningError(String::from_utf8(output.stderr) - .map_err(|e| CmusError::UnknownError(e.to_string()))?)); - } - - let output = String::from_utf8(output.stdout).map_err(|e| CmusError::UnknownError(e.to_string()))?; - - Track::from_str(&output).map_err(|e| CmusError::UnknownError(e.to_string())) + command } @@ -236,12 +248,34 @@ mod tests { } #[test] - #[ignore] - fn test_get_track() { - let track = get_track(&["cmus-remote"], None, None); + fn test_build_the_query_command_with_no_custom_socket_and_no_pass() { + let command = build_query_command("cmus-remote", &None, &None); - assert_matches!(track, Ok(_)); + assert_eq!(command.get_program(), "cmus-remote"); + assert_eq!(command.get_args().collect::>(), &["-Q"]); + } - println!("{:?}", track); + #[test] + fn test_build_the_query_command_with_custom_socket_and_no_pass() { + let command = build_query_command("cmus-remote", &Some("/tmp/cmus-socket".to_string()), &None); + + assert_eq!(command.get_program(), "cmus-remote"); + assert_eq!(command.get_args().collect::>(), &["--server", "/tmp/cmus-socket", "-Q"]); + } + + #[test] + fn test_build_the_query_command_with_custom_socket_and_pass() { + let command = build_query_command("cmus-remote", &Some("/tmp/cmus-socket".to_string()), &Some("pass".to_string())); + + assert_eq!(command.get_program(), "cmus-remote"); + assert_eq!(command.get_args().collect::>(), &["--server", "/tmp/cmus-socket", "--passwd", "pass", "-Q"]); + } + + #[test] + fn test_build_the_query_command_with_custom_bin_path() { + let command = build_query_command("flatpak run io.github.cmus.cmus", &None, &None); + + assert_eq!(command.get_program(), "flatpak"); + assert_eq!(command.get_args().collect::>(), &["run", "io.github.cmus.cmus", "-Q"]); } } diff --git a/src/main.rs b/src/main.rs index 336920e..4fa98eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,10 @@ mod cmus; use clap::Parser; fn main() { - let _args = arguments::Arguments::parse(); - println!("{_args:#?}"); + let args = arguments::Arguments::parse(); + + // Build the command, or use the default. (to speed up the main loop, because we don't need to build it every time) + let mut query_command = cmus::build_query_command( + &args.cmus_remote_bin_path.unwrap_or("cmus-remote".to_string()).as_str(), + &args.cmus_socket_address, &args.cmus_socket_password); }