use crate::{app::AppError, arg::Arg};
use std::collections::HashMap;
pub struct Command<'a> {
pub name: &'a str,
pub about: &'a str,
pub args: Vec<Arg<'a>>,
pub subcommands: HashMap<&'a str, Command<'a>>,
pub execute: Option<Box<dyn Fn(&Matches) + 'a>>,
}
impl<'a> Command<'a> {
pub fn new(name: &'a str) -> Self {
Command {
name,
about: "",
args: Vec::new(),
subcommands: HashMap::new(),
execute: None,
}
}
pub fn about(mut self, about: &'a str) -> Self {
self.about = about;
self
}
pub fn arg(mut self, arg: Arg<'a>) -> Self {
self.args.push(arg);
self
}
pub fn subcommand(mut self, subcommand: Command<'a>) -> Self {
self.subcommands.insert(subcommand.name, subcommand);
self
}
pub fn execute<F>(mut self, func: F) -> Self
where
F: Fn(&Matches) + 'a,
{
self.execute = Some(Box::new(func));
self
}
}
pub struct Matches {
pub args: HashMap<String, String>,
}
impl Matches {
pub fn new() -> Self {
Matches {
args: HashMap::new(),
}
}
pub fn insert(&mut self, key: &str, value: String) {
self.args.insert(key.to_string(), value);
}
pub fn value_of(&self, key: &str) -> Option<&String> {
self.args.get(key)
}
pub fn is_present(&self, key: &str) -> bool {
self.args.contains_key(key)
}
pub fn get(&self, key: &str) -> Result<&String, AppError> {
self.args.get(key).ok_or(AppError::MissingValue(key.to_string()))
}
}