Separate the command builder from the command runner to improve the performance
This commit is contained in:
parent
0832665fb2
commit
8ad8e3c190
2 changed files with 59 additions and 21 deletions
|
@ -136,11 +136,32 @@ impl Track {
|
||||||
/// Make a status request to cmus.
|
/// Make a status request to cmus.
|
||||||
/// And collect the output, and parse it into a `Track`.
|
/// 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.
|
/// 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<Track, CmusError> {
|
#[inline]
|
||||||
let mut command = std::process::Command::new(cmus_remote_bin[0]);
|
pub fn get_track(query_command: &mut std::process::Command) -> Result<Track, CmusError> {
|
||||||
|
// 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) {
|
if !output.status.success() {
|
||||||
command.arg(arg);
|
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<String>, socket_pass: &Option<String>) -> std::process::Command {
|
||||||
|
let cmd_arr = cmus_remote_bin.split_whitespace().collect::<Vec<_>>();
|
||||||
|
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 {
|
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");
|
command.arg("-Q");
|
||||||
|
|
||||||
let output = command.output().map_err(|e| CmusError::CmusRunningError(e.to_string()))?;
|
command
|
||||||
|
|
||||||
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()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,12 +248,34 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
fn test_build_the_query_command_with_no_custom_socket_and_no_pass() {
|
||||||
fn test_get_track() {
|
let command = build_query_command("cmus-remote", &None, &None);
|
||||||
let track = get_track(&["cmus-remote"], None, None);
|
|
||||||
|
|
||||||
assert_matches!(track, Ok(_));
|
assert_eq!(command.get_program(), "cmus-remote");
|
||||||
|
assert_eq!(command.get_args().collect::<Vec<_>>(), &["-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::<Vec<_>>(), &["--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::<Vec<_>>(), &["--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::<Vec<_>>(), &["run", "io.github.cmus.cmus", "-Q"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ mod cmus;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _args = arguments::Arguments::parse();
|
let args = arguments::Arguments::parse();
|
||||||
println!("{_args:#?}");
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue