diff --git a/src/main.rs b/src/main.rs index cb964b9..ba9d91d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ use crate::logger::{LogLevel, Logger}; use crate::os_str_extension::OsStrExtension; use crate::os_string_builder::ReplaceWithOsStr; use crate::server::{RelativeLocalPathAnker, ServerAddress}; +use crate::shell_interface::os_string_from_ssh_output; use clap::{Parser, Subcommand, ValueEnum}; use lazy_regex::{lazy_regex, Lazy, Regex}; use server::{Server, ServerReference}; @@ -243,7 +244,7 @@ where ))?; } - let denoted_files = osstring_from_ssh_output(output.stdout) + let denoted_files = os_string_from_ssh_output(output.stdout) .split(b'\n') //split at line breaks .into_iter() .filter(|bytes| !bytes.is_empty()) //needed since realpath sometimes gives us empty lines @@ -304,7 +305,7 @@ where server, actions: { let present_file_names: Vec = match &server.address { - ServerAddress::Ssh { ssh_address } => osstring_from_ssh_output( + ServerAddress::Ssh { ssh_address } => os_string_from_ssh_output( ShellCmd::new("ssh") .arg(ssh_address) .arg(osf!("ls ") + &working_directory) @@ -735,21 +736,6 @@ fn main() -> Result<(), String> { Application::::default().run() } -//This will be moved into the shell-interface -fn osstring_from_ssh_output(output: Vec) -> OsString { - #[cfg(unix)] - { - use std::os::unix::ffi::OsStringExt; - OsString::from_vec(output) - } - - #[cfg(windows)] - { - use std::os::windows::ffi::OsStringExt; - OsString::from_wide(output.iter().map(|&b| b as u16).collect()) - } -} - fn parse_server_configuration( config_str: &str, get_home_directory: F, diff --git a/src/shell_interface.rs b/src/shell_interface.rs index a19d4a7..645e5e9 100644 --- a/src/shell_interface.rs +++ b/src/shell_interface.rs @@ -3,10 +3,10 @@ use crate::logger::{LogLevel, Logger}; use std::error::Error; use std::ffi::OsString; use std::fmt::{Debug, Display, Formatter}; -use std::io; use std::iter::once; use std::path::PathBuf; -use std::process::Command; +use std::process::{Command, Output}; +use std::{io, process}; #[derive(Debug)] pub struct EnvCommand<'a, E> { @@ -123,7 +123,27 @@ pub trait ShellInterface { } } -//TODO implement shell interface for env command +impl ShellInterface for EnvCommand<'_, E> { + fn run(self) -> CommandResult { + CommandResult { + result: build_command_from_shell_command(&self.command) + .status() + .map(ExitStatus::from) + .map_err(StartError), + command: self.command, + } + } + + fn output(self) -> CommandResult { + CommandResult { + result: build_command_from_shell_command(&self.command) + .output() + .map(CommandOutput::from) + .map_err(StartError), + command: self.command, + } + } +} pub trait MaybeCast { fn maybe_cast(&self) -> Option<&T>; @@ -234,6 +254,31 @@ pub struct CommandOutput { pub status: ExitStatus, } +impl From for CommandOutput { + fn from(value: Output) -> Self { + Self { + stdout: os_string_from_ssh_output(value.stdout), + stderr: os_string_from_ssh_output(value.stderr), + status: value.status.into(), + } + } +} + +//TODO remove super visibility once it is not needed anymore +pub(super) fn os_string_from_ssh_output(output: Vec) -> OsString { + #[cfg(unix)] + { + use std::os::unix::ffi::OsStringExt; + OsString::from_vec(output) + } + + #[cfg(windows)] + { + use std::os::windows::ffi::OsStringExt; + OsString::from_wide(output.iter().map(|&b| b as u16).collect()) + } +} + impl AsRef for CommandOutput { fn as_ref(&self) -> &ExitStatus { &self.status @@ -247,6 +292,16 @@ pub struct ExitStatus { pub code: Option, } +impl From for ExitStatus { + fn from(value: process::ExitStatus) -> Self { + Self { + success: value.success(), + string_form: value.to_string(), + code: value.code(), + } + } +} + impl AsRef for ExitStatus { fn as_ref(&self) -> &ExitStatus { self @@ -283,6 +338,12 @@ impl Error for CommandError where E: Error {} #[derive(Debug)] pub struct StartError(io::Error); +impl From for StartError { + fn from(value: io::Error) -> Self { + StartError(value) + } +} + impl Display for StartError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "Failed to run command: {}", self.0)