use std::ffi::OsString;
use std::collections::HashMap;
use clap;
use super::{Context, ArgumentType};
use super::internal::{Feedback, CollectedCommand};
use super::CommandName;
pub struct ClapBackend;
impl ClapBackend {
#[doc(hidden)]
pub fn execute_cmd_string<I, T>(
commands: &HashMap<CommandName, CollectedCommand>,
line: I,
) -> Feedback
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let subcommands: Vec<_> = commands
.values()
.map(|command| ClapBackend::command_into_subcommand(command))
.collect();
let matches = clap::App::new("Exonum application based on fabric configuration.")
.setting(clap::AppSettings::ArgRequiredElseHelp)
.version(crate_version!())
.author(crate_authors!("\n"))
.about(
"It contain basic set of command, to deploy network on exonum.",
)
.subcommands(subcommands.into_iter())
.get_matches_from_safe(line)
.unwrap();
let subcommand = matches.subcommand();
let command = commands.get(subcommand.0).expect("Subcommand not found.");
command.execute(
commands,
Context::new_from_args(command.args(), subcommand.1.expect("Arguments not found.")),
)
}
pub fn execute(commands: &HashMap<CommandName, CollectedCommand>) -> Feedback {
let subcommands: Vec<_> = commands
.values()
.map(|command| ClapBackend::command_into_subcommand(command))
.collect();
let matches = clap::App::new("Exonum application based on fabric configuration.")
.setting(clap::AppSettings::ArgRequiredElseHelp)
.version(crate_version!())
.author(crate_authors!("\n"))
.about("Exonum application based on fabric configuration.")
.subcommands(subcommands.into_iter())
.get_matches();
let subcommand = matches.subcommand();
let command = commands.get(subcommand.0).expect("Subcommand not found.");
command.execute(
commands,
Context::new_from_args(command.args(), subcommand.1.expect("Arguments not found.")),
)
}
fn command_into_subcommand(command: &CollectedCommand) -> clap::App {
let mut index = 1;
let command_args: Vec<_> = command
.args()
.iter()
.map(|arg| {
let clap_arg = clap::Arg::with_name(arg.name);
let clap_arg = match arg.argument_type {
ArgumentType::Positional => {
let arg = clap_arg.index(index);
index += 1;
arg
}
ArgumentType::Named(detail) => {
let mut clap_arg = clap_arg.long(detail.long_name);
if let Some(short) = detail.short_name {
clap_arg = clap_arg.short(short);
}
clap_arg.multiple(detail.multiple).takes_value(true)
}
};
clap_arg.help(arg.help).required(arg.required)
})
.collect();
let mut subcommand = clap::SubCommand::with_name(command.name()).about(command.about());
subcommand = subcommand.args(&command_args);
subcommand
}
}