Ditch find_subcnd*! and match_alias!

This commit is contained in:
CreepySkeleton 2020-06-19 03:49:33 +03:00
parent f143b2f70e
commit f904bebd9a
6 changed files with 40 additions and 49 deletions

View file

@ -5,7 +5,7 @@
// Accept and endure. Do not touch. // Accept and endure. Do not touch.
#![allow(unused)] #![allow(unused)]
use clap::{find_subcmd_mut, match_alias, IntoApp}; use clap::IntoApp;
pub fn get_help<T: IntoApp>() -> String { pub fn get_help<T: IntoApp>() -> String {
let mut output = Vec::new(); let mut output = Vec::new();
@ -33,7 +33,8 @@ pub fn get_long_help<T: IntoApp>() -> String {
pub fn get_subcommand_long_help<T: IntoApp>(subcmd: &str) -> String { pub fn get_subcommand_long_help<T: IntoApp>(subcmd: &str) -> String {
let mut output = Vec::new(); let mut output = Vec::new();
find_subcmd_mut!(<T as IntoApp>::into_app(), subcmd) <T as IntoApp>::into_app()
.find_subcommand(subcmd)
.unwrap() .unwrap()
.write_long_help(&mut output) .write_long_help(&mut output)
.unwrap(); .unwrap();

View file

@ -4,7 +4,7 @@ mod shells;
use std::io::Write; use std::io::Write;
// Internal // Internal
use clap::{find_subcmd, match_alias, App, AppSettings, Arg}; use clap::{App, AppSettings, Arg};
pub use shells::*; pub use shells::*;
/// Generator trait which can be used to write generators /// Generator trait which can be used to write generators
@ -81,7 +81,7 @@ pub trait Generator {
let mut app = p; let mut app = p;
for sc in path { for sc in path {
app = find_subcmd!(app, sc).unwrap(); app = app.find_subcommand(sc).unwrap();
} }
app app

View file

@ -260,7 +260,7 @@ fn parser_of<'b>(p: &'b App<'b>, mut sc: &str) -> &'b App<'b> {
} }
sc = sc.split(' ').last().unwrap(); sc = sc.split(' ').last().unwrap();
find_subcmd!(p, sc).expect(INTERNAL_ERROR_MSG) p.find_subcommand(sc).expect(INTERNAL_ERROR_MSG)
} }
// Writes out the args section, which ends up being the flags, opts and postionals, and a jump to // Writes out the args section, which ends up being the flags, opts and postionals, and a jump to

View file

@ -202,6 +202,15 @@ impl<'b> App<'b> {
pub fn has_subcommands(&self) -> bool { pub fn has_subcommands(&self) -> bool {
!self.subcommands.is_empty() !self.subcommands.is_empty()
} }
/// Find subcommand such that its name or one of aliases equals `name`.
#[inline]
pub fn find_subcommand<T>(&self, name: &T) -> Option<&App<'b>>
where
T: PartialEq<str> + ?Sized,
{
self.get_subcommands().iter().find(|s| s.aliases_to(name))
}
} }
impl<'b> App<'b> { impl<'b> App<'b> {
@ -1940,6 +1949,7 @@ impl<'b> App<'b> {
self.args.args.iter().find(|a| a.id == *arg_id) self.args.args.iter().find(|a| a.id == *arg_id)
} }
#[inline]
// Should we color the output? // Should we color the output?
pub(crate) fn color(&self) -> ColorChoice { pub(crate) fn color(&self) -> ColorChoice {
debug!("App::color: Color setting..."); debug!("App::color: Color setting...");
@ -1956,6 +1966,7 @@ impl<'b> App<'b> {
} }
} }
#[inline]
pub(crate) fn contains_short(&self, s: char) -> bool { pub(crate) fn contains_short(&self, s: char) -> bool {
if !self.is_set(AppSettings::Built) { if !self.is_set(AppSettings::Built) {
panic!("If App::_build hasn't been called, manually search through Arg shorts"); panic!("If App::_build hasn't been called, manually search through Arg shorts");
@ -1964,22 +1975,27 @@ impl<'b> App<'b> {
self.args.contains(s) self.args.contains(s)
} }
#[inline]
pub(crate) fn set(&mut self, s: AppSettings) { pub(crate) fn set(&mut self, s: AppSettings) {
self.settings.set(s) self.settings.set(s)
} }
#[inline]
pub(crate) fn unset(&mut self, s: AppSettings) { pub(crate) fn unset(&mut self, s: AppSettings) {
self.settings.unset(s) self.settings.unset(s)
} }
#[inline]
pub(crate) fn has_args(&self) -> bool { pub(crate) fn has_args(&self) -> bool {
!self.args.is_empty() !self.args.is_empty()
} }
#[inline]
pub(crate) fn has_opts(&self) -> bool { pub(crate) fn has_opts(&self) -> bool {
self.get_opts_no_heading().count() > 0 self.get_opts_no_heading().count() > 0
} }
#[inline]
pub(crate) fn has_flags(&self) -> bool { pub(crate) fn has_flags(&self) -> bool {
self.get_flags_no_heading().count() > 0 self.get_flags_no_heading().count() > 0
} }
@ -1991,6 +2007,16 @@ impl<'b> App<'b> {
.any(|sc| !sc.is_set(AppSettings::Hidden)) .any(|sc| !sc.is_set(AppSettings::Hidden))
} }
/// Check if this subcommand can be referred to as `name`. In other words,
/// check if `name` is the name of this subcommand or is one of its aliases.
#[inline]
pub(crate) fn aliases_to<T>(&self, name: &T) -> bool
where
T: PartialEq<str> + ?Sized,
{
*name == *self.get_name() || self.get_all_aliases().any(|alias| *name == *alias)
}
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
pub(crate) fn id_exists(&self, id: &Id) -> bool { pub(crate) fn id_exists(&self, id: &Id) -> bool {
self.args.args.iter().any(|x| x.id == *id) || self.groups.iter().any(|x| x.id == *id) self.args.args.iter().any(|x| x.id == *id) || self.groups.iter().any(|x| x.id == *id)
@ -2012,7 +2038,6 @@ impl<'b> App<'b> {
self.get_subcommands().iter().map(|s| s.get_name()).chain( self.get_subcommands().iter().map(|s| s.get_name()).chain(
self.get_subcommands() self.get_subcommands()
.iter() .iter()
.filter(|s| !s.aliases.is_empty()) // REFACTOR
.flat_map(|s| s.aliases.iter().map(|&(n, _)| n)), .flat_map(|s| s.aliases.iter().map(|&(n, _)| n)),
) )
} }

View file

@ -552,40 +552,3 @@ macro_rules! debug {
macro_rules! debug { macro_rules! debug {
($($arg:tt)*) => {}; ($($arg:tt)*) => {};
} }
macro_rules! find_subcmd_cloned {
($app:expr, $sc:expr) => {{
$app.get_subcommands()
.iter()
.cloned()
.find(|a| match_alias!(a, $sc, a.get_name()))
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! find_subcmd {
($app:expr, $sc:expr) => {{
$app.get_subcommands()
.iter()
.find(|a| match_alias!(a, $sc, a.get_name()))
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! find_subcmd_mut {
($app:expr, $sc:expr) => {{
$app.get_subcommands_mut()
.iter_mut()
.find(|a| match_alias!(a, $sc, a.get_name()))
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_alias {
($a:expr, $to:expr, $what:expr) => {{
$what == $to || $a.get_all_aliases().any(|alias| alias == $to)
}};
}

View file

@ -733,7 +733,9 @@ where
if !external_subcommand { if !external_subcommand {
if let Some(ref pos_sc_name) = subcmd_name { if let Some(ref pos_sc_name) = subcmd_name {
let sc_name = find_subcmd!(self.app, *pos_sc_name) let sc_name = self
.app
.find_subcommand(pos_sc_name)
.expect(INTERNAL_ERROR_MSG) .expect(INTERNAL_ERROR_MSG)
.name .name
.clone(); .clone();
@ -848,7 +850,7 @@ where
return Some(sc); return Some(sc);
} }
} }
} else if let Some(sc) = find_subcmd!(self.app, arg_os) { } else if let Some(sc) = self.app.find_subcommand(arg_os) {
return Some(&sc.name); return Some(&sc.name);
} }
@ -872,18 +874,18 @@ where
help_help = true; help_help = true;
break; // Maybe? break; // Maybe?
} }
if let Some(id) = find_subcmd!(sc, cmd).map(|x| x.id.clone()) { if let Some(id) = sc.find_subcommand(cmd).map(|x| x.id.clone()) {
sc._propagate(Propagation::To(id)); sc._propagate(Propagation::To(id));
} }
if let Some(mut c) = find_subcmd_cloned!(sc, cmd) { if let Some(mut c) = sc.find_subcommand(cmd).cloned() {
c._build(); c._build();
sc = c; sc = c;
if i == cmds.len() - 1 { if i == cmds.len() - 1 {
break; break;
} }
} else if let Some(mut c) = find_subcmd_cloned!(sc, &cmd.to_string_lossy()) { } else if let Some(mut c) = sc.find_subcommand(&cmd.to_string_lossy()).cloned() {
c._build(); c._build();
sc = c; sc = c;
@ -1002,7 +1004,7 @@ where
mid_string.push_str(" "); mid_string.push_str(" ");
if let Some(x) = find_subcmd!(self.app, sc_name) { if let Some(x) = self.app.find_subcommand(sc_name) {
let id = x.id.clone(); let id = x.id.clone();
self.app._propagate(Propagation::To(id)); self.app._propagate(Propagation::To(id));
} }