#[derive(Debug, Clone)]
pub struct App<'a> {
name: &'a str,
version: &'a str,
args: Vec<String>,
command: Vec<(&'a str, &'a str)>,
option: Vec<(&'a str, &'a str)>,
}
impl<'a> App<'a> {
pub fn new(name: &'a str, version: &'a str) -> App<'a> {
let args = std::env::args().collect::<Vec<String>>();
App {
name,
version,
args,
command: vec![],
option: vec![],
}
}
pub fn cmd(mut self, cmd: &'a str, desc: &'a str) -> App<'a> {
self.command.push((cmd, desc));
App { ..self }
}
pub fn opt(mut self, opt: &'a str, desc: &'a str) -> App<'a> {
self.option.push((opt, desc));
App { ..self }
}
pub fn command(&self) -> Option<&String> {
if let Some(cur) = self.args.get(1) {
let all = self.option.iter().all(|(item, _)| item != cur);
if all {
return Some(cur);
}
}
None
}
pub fn is(&mut self, arg: &str) -> bool {
self.args.len() > 1 && arg == self.args[1]
}
pub fn values(&self) -> &[String] {
&self.args[1..]
}
pub fn value(&self, option: &str) -> Option<Vec<&String>> {
let mut values = vec![];
let mut find = false;
for item in self.args[1..].iter() {
if find {
let all = self.option.iter().all(|(arg, _)| item != arg);
if all {
values.push(item);
} else {
break;
}
}
if item == option {
find = true;
}
}
if find {
Some(values)
} else {
None
}
}
pub fn version(&self) {
println!("{0} version {1}", self.name, self.version)
}
fn print_help(name: &'static str, data: &Vec<(&str, &str)>) {
println!("{}", name);
let mut n = 0;
data.iter().for_each(|(d, _)| {
if d.len() > n {
n = d.len();
}
});
for (arg, desc) in data {
println!(" {:arg$} {}", arg, desc, arg = n);
}
}
pub fn help(&self) {
println!(
"\
{0} version {1}
Usage:
{0} [COMMAND] [OPTION]
",
self.name, self.version
);
if self.command.len() > 0 {
Self::print_help("Command:", &self.command);
}
if self.command.len() > 0 && self.option.len() > 0 {
println!();
}
if self.option.len() > 0 {
Self::print_help("Option:", &self.option);
}
}
pub fn error(&self) {
eprint!("\x1B[1;31m{}\x1B[0m", "error: ");
eprintln!(
"'{}' is not a valid command",
self.args.get(1).unwrap_or(&String::new())
);
}
pub fn error_try(&self, command: &str) {
self.error();
eprintln!("try:\n '{} {}'", self.name, command);
}
}