diff options
Diffstat (limited to 'src/utils.rs')
-rw-r--r-- | src/utils.rs | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/src/utils.rs b/src/utils.rs index 74e49e977..b46bda7af 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,7 +1,9 @@ use process_control::{ChildExt, Timeout}; +use starship_cache::CachedOutput; +use std::convert::TryFrom; use std::fmt::Debug; use std::fs::read_to_string; -use std::io::Result; +use std::io; use std::path::Path; use std::process::{Command, Stdio}; use std::time::{Duration, Instant}; @@ -9,7 +11,7 @@ use std::time::{Duration, Instant}; use crate::context::Shell; /// Return the string contents of a file -pub fn read_file<P: AsRef<Path> + Debug>(file_name: P) -> Result<String> { +pub fn read_file<P: AsRef<Path> + Debug>(file_name: P) -> io::Result<String> { log::trace!("Trying to read from {:?}", file_name); let result = read_to_string(file_name); @@ -30,6 +32,43 @@ pub struct CommandOutput { pub status: i64, } +impl TryFrom<process_control::Output> for CommandOutput { + type Error = String; + + fn try_from(output: process_control::Output) -> Result<Self, Self::Error> { + let stdout = String::from_utf8(output.stdout) + .map_err(|err| format!("Unable to decode stdout: {:?}", err))?; + let stderr = String::from_utf8(output.stderr) + .map_err(|err| format!("Unable to decode stderr: {:?}", err))?; + + Ok(Self { + stdout, + stderr, + status: output.status.code().unwrap_or_default(), + }) + } +} + +impl From<&CachedOutput> for CommandOutput { + fn from(output: &CachedOutput) -> Self { + Self { + stdout: output.stdout.to_owned(), + stderr: output.stderr.to_owned(), + status: output.status.unwrap_or_default() as i64 + } + } +} + +impl Into<CachedOutput> for &CommandOutput { + fn into(self) -> CachedOutput { + CachedOutput { + stdout: self.stdout.clone(), + stderr: self.stdout.clone(), + status: Some(i32::try_from(self.status).unwrap_or_default()) + } + } +} + /// Execute a command and return the output on stdout and stderr if successful #[cfg(not(test))] pub fn exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<CommandOutput> { @@ -305,7 +344,7 @@ pub fn wrap_seq_for_shell( } fn internal_exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<CommandOutput> { - log::trace!("Executing command {:?} with args {:?}", cmd, args); + let start = Instant::now(); let full_path = match which::which(cmd) { Ok(full_path) => { @@ -318,8 +357,6 @@ fn internal_exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<C } }; - let start = Instant::now(); - let process = match Command::new(full_path) .args(args) .stderr(Stdio::piped()) @@ -336,38 +373,19 @@ fn internal_exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<C match process.with_output_timeout(time_limit).terminating().wait() { Ok(Some(output)) => { - let stdout_string = match String::from_utf8(output.stdout) { - Ok(stdout) => stdout, - Err(error) => { - log::warn!("Unable to decode stdout: {:?}", error); - return None; - } - }; - let stderr_string = match String::from_utf8(output.stderr) { - Ok(stderr) => stderr, - Err(error) => { - log::warn!("Unable to decode stderr: {:?}", error); - return None; - } - }; + let output = CommandOutput::try_from(output) + .map_err(|err| log::warn!("{}", err)) + .ok()?; log::trace!( "stdout: {:?}, stderr: {:?}, exit code: \"{:?}\", took {:?}", - stdout_string, - stderr_string, - output.status.code(), + output.stdout, + output.stderr, + output.status, start.elapsed() ); - if !output.status.success() { - return None; - } - - Some(CommandOutput { - stdout: stdout_string, - stderr: stderr_string, - status: output.status.code().unwrap_or_default() - }) + Some(output) } Ok(None) => { log::warn!("Executing command {:?} timed out.", cmd); |