use std::{
env, io,
fmt::Display,
path::{Path, PathBuf},
ffi::OsStr,
process::{
Child,
Command,
Stdio
}
};
pub struct CommandOutput {
pub output: String,
pub code: u32
}
impl CommandOutput {
pub fn success(&self) -> bool {
self.code == 0
}
}
#[track_caller]
pub fn run_command<A: IntoIterator<Item = S> + Clone, S: AsRef<OsStr>>(prog: &str, superuser: bool, args: A) -> CommandOutput {
let mut cmd = if superuser {
let mut cmd_t = Command::new("sudo");
cmd_t.arg(prog);
cmd_t
}
else { Command::new(prog) };
cmd.args(args);
let output = match cmd.output() {
Ok(o) => o,
Err(why) => {
return CommandOutput {
output: why.to_string(),
code: 666
};
}
};
let code = output.status.code().unwrap_or(1) as u32;
let mut o_fmt = if code == 0 {
String::from_utf8(output.stdout).unwrap()
}
else {
String::from_utf8(output.stderr).unwrap()
};
o_fmt.pop();
CommandOutput {
output: o_fmt,
code: output.status.code().unwrap_or(1) as u32
}
}
#[track_caller]
pub fn spawn_process<A: IntoIterator<Item = S> + Clone, S: AsRef<OsStr>>(prog: &str, superuser: bool, should_output: bool, args: A) -> Child {
let mut cmd = if superuser {
let mut cmd_t = Command::new("sudo");
cmd_t.arg(prog);
cmd_t
}
else {
Command::new(prog)
};
if !should_output {
cmd.stdout(Stdio::null());
cmd.stderr(Stdio::null());
}
cmd.args(args);
cmd.spawn().unwrap()
}
pub fn alphabetize<L: Display>(list: &[L]) -> Vec<String> {
let mut string_list: Vec<String> = list.iter().map(L::to_string).collect();
string_list.sort_unstable_by_key(|a| a.to_lowercase());
string_list
}
pub fn get_filename<D: Into<PathBuf>>(dir: D) -> String {
let path = dir.into();
if let Some(file_name) = path.file_name() {
file_name.to_str().unwrap().to_string()
}
else { String::new() }
}
pub fn get_parent<D: Into<PathBuf>>(dir: D) -> String {
let path = dir.into();
if let Some(parent) = path.parent() {
parent.display().to_string()
}
else {
path.display().to_string()
}
}
pub fn capitalize<W: Display>(word: W) -> String {
let s1 = word.to_string();
let mut v: Vec<char> = s1.chars().collect();
for item in &mut v {
if item.is_ascii_alphanumeric() {
*item = item.to_ascii_uppercase();
break;
}
}
let s2: String = v.into_iter().collect();
s2
}
#[track_caller]
pub fn get_execname() -> String {
env::args().next()
.as_ref()
.map(Path::new)
.and_then(Path::file_name)
.and_then(OsStr::to_str)
.map(String::from)
.unwrap()
}
#[track_caller]
pub fn get_input<M: Display>(msg: M) -> String {
println!("{msg}");
let mut buf_string = String::new();
io::stdin().read_line(&mut buf_string).unwrap();
buf_string.retain(|c| c != '\n');
buf_string
}