use clap::clap_app;
use crate::error::RadError;
use crate::auth::AuthType;
use crate::processor::Processor;
use crate::utils::Utils;
use std::path::{Path, PathBuf};
pub struct Cli{
rules: Option<Vec<PathBuf>>,
write_to_file : Option<PathBuf>,
error_to_file : Option<PathBuf>,
allow_auth: Option<Vec<AuthType>>,
allow_auth_warn: Option<Vec<AuthType>>,
}
impl Cli {
pub fn new() -> Self {
Self {
rules: None,
write_to_file : None,
error_to_file : None,
allow_auth : None,
allow_auth_warn : None,
}
}
pub fn parse(&mut self) -> Result<(), RadError>{
let cli_args = Cli::args_builder();
self.run_processor(&cli_args)?;
Ok(())
}
fn run_processor(&mut self, args: & clap::ArgMatches) -> Result<(), RadError> {
self.parse_options(args);
let mut processor = Processor::new()
.purge(args.is_present("purge"))
.greedy(args.is_present("greedy"))
.lenient(args.is_present("lenient"))
.silent(args.is_present("silent"))
.nopanic(args.is_present("nopanic"))
.allow(std::mem::replace(&mut self.allow_auth,None))
.allow_with_warning(std::mem::replace(&mut self.allow_auth_warn,None))
.unix_new_line(args.is_present("newline"))
.custom_rules(std::mem::replace(&mut self.rules,None))?
.write_to_file(std::mem::replace(&mut self.write_to_file,None))?
.discard(args.is_present("discard"))
.error_to_file(std::mem::replace(&mut self.error_to_file,None))?
.debug(args.is_present("debug"))
.log(args.is_present("log"))
.diff(args.is_present("diff"))?
.interactive(args.is_present("interactive"))
.build();
#[cfg(feature = "debug")]
if args.is_present("debug") {
Utils::clear_terminal()?;
}
processor.print_permission()?;
if let Some(files) = args.values_of("FILE") {
if args.is_present("combination") {
processor.from_stdin()?;
}
for file in files {
processor.from_file(Path::new(file))?;
}
} else { processor.from_stdin()?;
}
processor.print_result()?;
if let Some(file) = args.value_of("freeze") {
processor.freeze_to_file(Path::new(file))?;
}
Ok(())
}
fn parse_options(&mut self, args: & clap::ArgMatches) {
self.rules = if let Some(files) = args.values_of("melt") {
let files = files.into_iter().map(|value| PathBuf::from(value)).collect::<Vec<PathBuf>>();
Some(files)
} else { None };
self.write_to_file = if let Some(output_file) = args.value_of("out") {
Some(PathBuf::from(output_file))
} else { None };
self.error_to_file = if let Some(error_file) = args.value_of("err") {
Some(PathBuf::from(error_file))
} else { None };
self.allow_auth = if let Some(auths) = args.value_of("allow") {
auths.split("+").map(|s| AuthType::from(s)).collect()
} else { None };
self.allow_auth_warn = if let Some(auths) = args.value_of("allow_warn") {
auths.split("+").map(|s| AuthType::from(s)).collect()
} else { None };
if args.is_present("allow_all") {
self.allow_auth = Some(
vec![
AuthType::FIN,
AuthType::FOUT,
AuthType::ENV,
AuthType::CMD
]
);
}
if args.is_present("allow_all_warn") {
self.allow_auth_warn = Some(
vec![
AuthType::FIN,
AuthType::FOUT,
AuthType::ENV,
AuthType::CMD
]
);
}
}
fn args_builder() -> clap::ArgMatches {
clap_app!(rad =>
(version: "0.11.5")
(author: "Simon Creek <simoncreek@tutanota.com>")
(about: "R4d is a modern macro processor made with rust")
(@arg FILE: ... "Files to execute processing")
(@arg out: -o --out +takes_value conflicts_with[discard] "File to print out macro")
(@arg err: -e --err +takes_value "File to save logs")
(@arg greedy: -g --greedy "Make all macro invocation greedy")
(@arg melt: ... -m --melt +takes_value "Frozen file to reads")
(@arg freeze: -f --freeze +takes_value "Freeze to file")
(@arg purge: -p --purge "Purge unused macros")
(@arg lenient: -l --lenient "Lenient mode, disables strict mode")
(@arg nopanic: --nopanic "Don't panic in any circumstances, the most lenient mode")
(@arg debug: -d --debug "Debug mode")
(@arg log: --log "Debug log mode")
(@arg diff: --diff "Show diff result")
(@arg interactive: -i --interactive "Use interactive debug mode")
(@arg combination: -c "Read from both stdin and file inputs")
(@arg discard: -D --discard "Discard output")
(@arg allow: -a +takes_value "Allow permission (fin|fout|cmd|env)")
(@arg allow_warn: -w +takes_value "Allow permission with warnings (fin|fout|cmd|env)")
(@arg allow_all: -A conflicts_with[allow_all_warn] "Allow all permission")
(@arg allow_all_warn: -W "Allow all permission with warning")
(@arg silent: -s "Supress warnings")
(@arg newline: -n "Use unix newline for formatting")
).get_matches()
}
}