use crate::command::{parse_command, Command, CommandResult};
use crate::error::*;
use crate::help;
use crate::value::build_values;
use std::io::Write;
fn parse_and_execute_impl<E, W: Write>(
program: &str,
args: &[String],
mut commands: Vec<Command<E>>,
mut output_writer: Option<W>,
print_program_help: bool,
print_command_name: bool,
) -> Result<Option<CommandResult<E>>> {
let mut args_iterator = args.iter().peekable();
let command_idx = match parse_command(&mut args_iterator, &commands) {
Ok(c) => c,
Err(e) => {
if print_program_help {
help::print_program_help(output_writer.as_mut(), program, &commands, e)?;
}
return Ok(None);
}
};
let mut command = commands.remove(command_idx);
let values = match build_values(&command.flags, args_iterator) {
Ok(vs) => vs,
Err(e) => {
help::print_command_help(
output_writer.as_mut(),
program,
&command,
print_command_name,
e,
)?;
return Ok(None);
}
};
Ok(Some(command.execute(values)))
}
pub(crate) fn parse_and_execute<E, W: Write>(
program: &str,
args: &[String],
commands: Vec<Command<E>>,
output_writer: Option<W>,
) -> Result<Option<CommandResult<E>>> {
parse_and_execute_impl(program, args, commands, output_writer, true, true)
}
pub(crate) fn parse_and_execute_single_command<E, W: Write>(
program: &str,
args: &[String],
command: Command<E>,
output_writer: Option<W>,
) -> Result<Option<CommandResult<E>>> {
let args: Vec<String> = Some(command.name.clone())
.into_iter()
.chain(args.iter().cloned())
.collect();
parse_and_execute_impl(
program,
args.as_slice(),
vec![command],
output_writer,
false,
false,
)
}