use crate::action::Action;
use crate::args::{Args, ArgsNew};
use std::collections::HashMap;
use std::env;
pub struct ActionApp {
pub command: String, pub alias: Vec<String>,
pub action: Box<dyn Action>,
}
pub struct Cmd {
raw_args: Vec<String>,
calls: HashMap<String, Box<dyn FnMut(&Args)>>, actions: Vec<ActionApp>, action_default: Option<Box<dyn FnMut(&Args)>>, action_no_handler: Option<Box<dyn FnMut(&Args)>>, args: Option<Args>,
}
pub fn get_os_args() -> Vec<String> {
let mut args: Vec<String> = Vec::new();
let mut idx = 0;
for arg in env::args() {
if idx < 1 {
idx += 1;
continue;
}
args.push(arg);
}
args
}
pub trait CmdFromOs {
fn new() -> Cmd;
}
pub trait CmdFromArgs {
fn new(param: Vec<&str>) -> Cmd;
}
impl Cmd {
pub fn from(param: Vec<&str>) -> Cmd {
let mut args: Vec<String> = Vec::new();
for arg in param {
args.push(String::from(arg));
}
let mut app = Cmd {
raw_args: args,
calls: HashMap::new(),
action_default: None,
action_no_handler: None,
args: None,
actions: Vec::new(),
};
app.parse_args();
return app;
}
fn get_os_args(&mut self) {
self.raw_args = get_os_args();
}
fn parse_args(&mut self) {
if self.raw_args.is_empty() {
self.get_os_args()
}
}
pub fn register<F>(&mut self, name: &str, action: F) -> &mut Cmd
where
F: FnMut(&Args) + 'static,
{
self.calls.insert(String::from(name), Box::new(action));
self
}
pub fn register_action(&mut self, app: Box<ActionApp>) -> &mut Cmd {
self.actions.push(*app);
self
}
pub fn empty<F>(&mut self, action: F) -> &mut Cmd
where
F: FnMut(&Args) + 'static,
{
self.action_default = Some(Box::new(action));
self
}
pub fn un_found<F>(&mut self, action: F) -> &mut Cmd
where
F: FnMut(&Args) + 'static,
{
self.action_no_handler = Some(Box::new(action));
self
}
pub fn run(mut self) {
let args = Args::new(&self.raw_args);
self.args = Some(args);
for (v_key, mut v_fn) in self.calls {
if self.args.as_ref().unwrap().command == String::from(v_key) {
v_fn(self.args.as_ref().unwrap());
return;
}
}
for action in &self.actions {
if action.command == self.args.as_ref().unwrap().command {
action.action.as_ref().run(self.args.as_ref().unwrap());
return;
} else {
for alias in &action.alias {
if String::from(alias) == self.args.as_ref().unwrap().command {
action.action.as_ref().run(self.args.as_ref().unwrap());
return;
}
}
}
}
if !self.action_no_handler.is_none() && !self.args.as_ref().unwrap().command.is_empty() {
(self.action_no_handler.unwrap())(self.args.as_ref().unwrap());
return;
}
if !self.action_default.is_none() {
(self.action_default.unwrap())(self.args.as_ref().unwrap());
}
}
}
impl CmdFromOs for Cmd {
fn new() -> Cmd {
let mut cmd = Cmd::from(vec![]);
cmd.get_os_args();
cmd
}
}
impl CmdFromArgs for Cmd {
fn new(param: Vec<&str>) -> Cmd {
Cmd::from(param)
}
}