|
|
|
@ -1,4 +1,7 @@
|
|
|
|
|
use super::*;
|
|
|
|
|
use std::{
|
|
|
|
|
path::{Path,PathBuf,},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
impl ProcessArgs
|
|
|
|
|
{
|
|
|
|
@ -23,14 +26,97 @@ impl ProcessArgs
|
|
|
|
|
Ok(Self{
|
|
|
|
|
name,
|
|
|
|
|
args,
|
|
|
|
|
name_real: None,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn verify(&self) -> Result<(), &'static str>
|
|
|
|
|
pub fn name_path(&self) -> Result<&Path, &'static str>
|
|
|
|
|
{
|
|
|
|
|
//TODO: Check file path of executable
|
|
|
|
|
Ok(())
|
|
|
|
|
if let Some(buf) = &self.name_real {
|
|
|
|
|
Ok(buf.as_ref())
|
|
|
|
|
} else {
|
|
|
|
|
Err("No name_path specified, have you called `verify()`?")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn verify(&self) -> Result<PathBuf, &'static str>
|
|
|
|
|
{
|
|
|
|
|
if let Ok(spath) = std::env::var("PATH") {
|
|
|
|
|
if let Some(path) = find_somewhere(&self.name, spath.split(':')) {
|
|
|
|
|
Ok(path)
|
|
|
|
|
} else {
|
|
|
|
|
Err("File not found")
|
|
|
|
|
}
|
|
|
|
|
} else if Path::new(&self.name).exists() {
|
|
|
|
|
Ok(Path::new(&self.name).to_owned())
|
|
|
|
|
} else {
|
|
|
|
|
Err("File not found and $PATH not found.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO: impl fmt::Display for ProcessArgs
|
|
|
|
|
fn find_somewhere<T,U,V>(name: T, places: U) -> Option<PathBuf>
|
|
|
|
|
where T: AsRef<str>,
|
|
|
|
|
U: Iterator<Item=V>,
|
|
|
|
|
V: AsRef<str>
|
|
|
|
|
{
|
|
|
|
|
let name = name.as_ref();
|
|
|
|
|
|
|
|
|
|
let pbuf = Path::new(&name);
|
|
|
|
|
if pbuf.exists() {
|
|
|
|
|
return Some(pbuf.to_owned())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for place in places
|
|
|
|
|
{
|
|
|
|
|
let place = place.as_ref();
|
|
|
|
|
|
|
|
|
|
let pbuf = Path::new(&place).join(&name);
|
|
|
|
|
if pbuf.exists() {
|
|
|
|
|
return Some(pbuf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn escape<T>(s: &T) -> String
|
|
|
|
|
where T: AsRef<str> + ?Sized
|
|
|
|
|
{
|
|
|
|
|
let s = s.as_ref();
|
|
|
|
|
let mut o = String::with_capacity(s.len());
|
|
|
|
|
|
|
|
|
|
for c in s.chars() {
|
|
|
|
|
match c {
|
|
|
|
|
'\\' => {
|
|
|
|
|
o.push('\\');
|
|
|
|
|
o.push('\\');
|
|
|
|
|
},
|
|
|
|
|
'\'' => {
|
|
|
|
|
o.push('\\');
|
|
|
|
|
o.push('\'');
|
|
|
|
|
},
|
|
|
|
|
other => o.push(other),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use std::fmt;
|
|
|
|
|
impl fmt::Display for ProcessArgs
|
|
|
|
|
{
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
|
|
|
|
{
|
|
|
|
|
write!(f, "{} ", self.name)?;
|
|
|
|
|
let len = self.args.len();
|
|
|
|
|
for (i,x) in (0..len).zip(self.args.iter()) {
|
|
|
|
|
write!(f, "{}", &x)?;
|
|
|
|
|
if i < len-1 {
|
|
|
|
|
write!(f, " ")?;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|