1use std::{
7 env, io,
8 fmt::Display,
9 path::{Path, PathBuf},
10 ffi::OsStr,
11 process::{
12 Child,
13 Command,
14 Stdio
15 }
16};
17
18pub struct CommandOutput {
22 pub output: String,
24
25 pub code: u32
29}
30
31impl CommandOutput {
32 pub fn success(&self) -> bool {
34 self.code == 0
35 }
36}
37
38#[track_caller]
40pub fn run_command<A: IntoIterator<Item = S> + Clone, S: AsRef<OsStr>>(prog: &str, superuser: bool, args: A) -> CommandOutput {
41 let mut cmd = if superuser {
42 let mut cmd_t = Command::new("sudo");
43 cmd_t.arg(prog);
44 cmd_t
45 }
46 else { Command::new(prog) };
47
48 cmd.args(args);
49
50 let output = match cmd.output() {
51 Ok(o) => o,
52 Err(why) => {
53 return CommandOutput {
54 output: why.to_string(),
55 code: 666
56 };
57 }
58 };
59
60 let code = output.status.code().unwrap_or(1) as u32;
61
62 let mut o_fmt = if code == 0 {
63 String::from_utf8(output.stdout).unwrap()
64 }
65 else {
66 String::from_utf8(output.stderr).unwrap()
67 };
68
69 o_fmt.pop();
70
71 CommandOutput {
72 output: o_fmt,
73 code: output.status.code().unwrap_or(1) as u32
74 }
75}
76
77#[track_caller]
79pub fn spawn_process<A: IntoIterator<Item = S> + Clone, S: AsRef<OsStr>>(prog: &str, superuser: bool, should_output: bool, args: A) -> Child {
80 let mut cmd = if superuser {
81 let mut cmd_t = Command::new("sudo");
82 cmd_t.arg(prog);
83 cmd_t
84 }
85 else {
86 Command::new(prog)
87 };
88
89 if !should_output {
90 cmd.stdout(Stdio::null());
91 cmd.stderr(Stdio::null());
92 }
93
94 cmd.args(args);
95 cmd.spawn().unwrap()
96}
97
98pub fn alphabetize<L: Display>(list: &[L]) -> Vec<String> {
100 let mut string_list: Vec<String> = list.iter().map(L::to_string).collect();
102 string_list.sort_unstable_by_key(|a| a.to_lowercase());
103 string_list
104}
105
106pub fn get_filename<D: Into<PathBuf>>(dir: D) -> String {
110 let path = dir.into();
111 if let Some(file_name) = path.file_name() {
112 file_name.to_str().unwrap().to_string()
113 }
114 else { String::new() }
115}
116
117pub fn get_parent<D: Into<PathBuf>>(dir: D) -> String {
121 let path = dir.into();
122 if let Some(parent) = path.parent() {
123 parent.display().to_string()
124 }
125 else {
126 path.display().to_string()
127 }
128}
129
130pub fn capitalize<W: Display>(word: W) -> String {
132 let s1 = word.to_string();
133 let mut v: Vec<char> = s1.chars().collect();
134
135 for item in &mut v {
136 if item.is_ascii_alphanumeric() {
137 *item = item.to_ascii_uppercase();
138 break;
139 }
140 }
141
142 let s2: String = v.into_iter().collect();
143 s2
144}
145
146#[track_caller]
148pub fn get_execname() -> String {
149 env::args().next()
150 .as_ref()
151 .map(Path::new)
152 .and_then(Path::file_name)
153 .and_then(OsStr::to_str)
154 .map(String::from)
155 .unwrap()
156}
157
158#[track_caller]
161pub fn get_input<M: Display>(msg: M) -> String {
162 println!("{msg}");
163 let mut buf_string = String::new();
164 io::stdin().read_line(&mut buf_string).unwrap();
165 buf_string.retain(|c| c != '\n');
166 buf_string
167}