91 lines
2.2 KiB
Rust
91 lines
2.2 KiB
Rust
use crate::{
|
|
context::Context,
|
|
opt::{self, Opt},
|
|
vox, App,
|
|
};
|
|
|
|
pub type Handler = fn(&App, &Context, &[String]);
|
|
|
|
#[derive(Clone)]
|
|
pub struct Command {
|
|
pub name: String,
|
|
pub commands: Vec<Command>,
|
|
pub handler: Option<Handler>,
|
|
pub opts: Vec<opt::Opt>,
|
|
pub long_desc: Option<String>,
|
|
pub short_desc: Option<String>,
|
|
}
|
|
|
|
impl Command {
|
|
pub fn new<T: Into<String>>(name: T) -> Self {
|
|
Command {
|
|
name: name.into(),
|
|
commands: vec![],
|
|
handler: None,
|
|
opts: vec![],
|
|
long_desc: None,
|
|
short_desc: None,
|
|
}
|
|
}
|
|
|
|
pub fn handler(mut self, f: Handler) -> Self {
|
|
self.handler = Some(f);
|
|
self
|
|
}
|
|
|
|
pub fn opt(mut self, opt: Opt) -> Self {
|
|
self.opts.push(opt);
|
|
self
|
|
}
|
|
|
|
pub fn short_desc(mut self, short_desc: &str) -> Self {
|
|
self.short_desc = Some(short_desc.into());
|
|
self
|
|
}
|
|
|
|
pub fn long_desc(mut self, long_desc: &str) -> Self {
|
|
self.short_desc = Some(long_desc.into());
|
|
self
|
|
}
|
|
}
|
|
|
|
pub(crate) fn help(app: &App, _ctx: &Context, args: &[String]) {
|
|
vox::print(app.application_header());
|
|
print_command_help(&app.root, args);
|
|
}
|
|
|
|
pub(crate) fn print_command_help(cmd: &Command, args: &[String]) {
|
|
if !args.is_empty() {
|
|
if let Some(cmd) = cmd.commands.iter().find(|c| Some(&c.name) == args.first()) {
|
|
return print_command_help(cmd, &args[1..]);
|
|
}
|
|
}
|
|
vox::print("");
|
|
if let Some(desc) = cmd.long_desc.as_ref().or(cmd.short_desc.as_ref()) {
|
|
if cmd.name != "root" {
|
|
vox::header(&cmd.name.to_uppercase());
|
|
}
|
|
vox::print(desc);
|
|
vox::print("");
|
|
}
|
|
if !cmd.opts.is_empty() {
|
|
vox::header("OPTIONS");
|
|
vox::description_list(
|
|
cmd.opts
|
|
.iter()
|
|
.map(|o| (o.usage(), o.desc.clone().unwrap_or_default()))
|
|
.collect(),
|
|
)
|
|
}
|
|
|
|
if !cmd.commands.is_empty() {
|
|
vox::header("Subcommands");
|
|
vox::description_list(
|
|
cmd.commands
|
|
.iter()
|
|
.map(|c| (c.name.clone(), c.short_desc.clone().unwrap_or_default()))
|
|
.collect(),
|
|
)
|
|
}
|
|
}
|