use std::collections::HashMap;
use base::Result;
use base::{ConstantSize, VariableSize};
use base::Datable;
use app::command::Request;
use app::{Env, Config, Logger, Manager};
pub trait CLI<M, E, C, L, D, MnP, A, StP, SvP, ClP, CP, AAd, AP, AR>
where M: Manager<E, C, D, MnP, A, StP, SvP, ClP, CP, AAd, AP, AR>,
E: Env,
C: Config<D, MnP, A, StP, SvP, ClP, CP>,
L: Logger,
D: Datable + ConstantSize,
MnP: Datable,
A: Ord + Datable + VariableSize,
StP: Datable,
SvP: Datable,
ClP: Datable,
CP: Datable,
AAd: Ord + Datable,
AP: Datable,
AR: Datable
{
fn env(&self) -> E;
fn config(&self) -> C;
fn logger(&self) -> L;
fn create_manager(&mut self, manager_params: &MnP) -> Result<()>;
fn manager(&self) -> Option<M>;
fn log_result<T: Sized>(&mut self, res: &Result<T>);
fn parse_vars_and_args(&mut self, vars: &HashMap<String, String>, args: &Vec<String>) -> Result<Request<AAd, AP>>;
fn parse_cmd(&mut self) -> Result<Request<AAd, AP>> {
let res_vars = self.env().vars();
self.log_result(&res_vars);
let res_args = self.env().args();
self.log_result(&res_args);
let vars = res_vars?;
let args = res_args?;
self.parse_vars_and_args(&vars, &args)
}
fn run(&mut self) {
let env = self.env();
let config = self.config();
let config_check = config.check();
self.log_result(&config_check);
let res_req = self.parse_cmd();
self.log_result(&res_req);
let req = res_req.unwrap();
if let Some(mut manager) = self.manager() {
manager.exec(&env, &config, &req)
} else {
let res = self.create_manager(&config.manager_params());
self.log_result(&res);
res.unwrap();
self.manager().unwrap().exec(&env, &config, &req)
}
}
}