use crate::{
command::{FliCallbackData, FliCommand},
display,
error::{FliError, Result},
option_parser::{InputArgsParser, Value, ValueTypes},
};
pub struct Fli {
pub name: String,
pub version: String,
pub description: String,
pub root_command: FliCommand, }
impl Fli {
pub fn command(&mut self, name: &str, description: &str) -> Result<&mut FliCommand> {
Ok(self.root_command.subcommand(name, description))
}
pub fn add_command(&mut self, command: FliCommand) {
self.root_command.add_sub_command(command);
}
pub fn set_callback(&mut self, callback: fn(&FliCallbackData)) {
self.root_command.set_callback(callback);
}
pub fn add_option(
&mut self,
name: &str,
description: &str,
short_flag: &str,
long_flag: &str,
value: ValueTypes,
) {
self.root_command
.add_option(name, description, short_flag, long_flag, value);
}
pub fn mark_inheritable(&mut self, flag: &str) -> Result<()> {
self.root_command.get_option_parser().mark_inheritable(flag)
}
pub fn mark_inheritable_many<I, S>(&mut self, flags: I) -> Result<()>
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
self.root_command
.get_option_parser()
.mark_inheritable_many(flags)
}
}
impl Fli {
pub fn new(name: &str, version: &str, description: &str) -> Self {
Self {
name: name.to_owned(),
version: version.to_owned(),
description: description.to_owned(),
root_command: FliCommand::new("", description),
}
}
pub fn run(&mut self) {
let args: Vec<String> = std::env::args().collect();
display::debug_print("App", &format!("Running {} v{}", self.name, self.version));
display::debug_struct("Arguments", &args);
let command_args = if args.len() > 1 {
args[1..].to_vec()
} else {
Vec::new()
};
let parser = InputArgsParser::new(self.root_command.get_name().to_string(), command_args);
match self.root_command.run(parser) {
Ok(_) => {
display::debug_print("App", "Execution completed successfully");
}
Err(e) => {
display::print_error_detailed(
"Command Execution Failed",
&e.to_string(),
Some("Run with --help for usage information"),
);
if let FliError::UnknownCommand(cmd, available) = e {
display::print_did_you_mean(&cmd, &available);
}
std::process::exit(1);
}
}
}
}
impl Fli {
pub fn with_debug(mut self) -> Self {
display::enable_debug();
self
}
pub fn add_debug_option(&mut self) {
self.root_command.add_option_with_callback(
"debug",
"Enable debug output",
"-D",
"--debug",
ValueTypes::OptionalSingle(Some(Value::Bool(false))),
false,
|data| {
display::enable_debug();
},
);
self.mark_inheritable("--debug").unwrap();
if std::env::args().any(|arg| arg == "-D" || arg == "--debug") {
display::enable_debug();
}
}
}