mirror of
https://github.com/clap-rs/clap
synced 2024-12-04 18:19:13 +00:00
wip refactoring shorts and longs into an arg key
This commit is contained in:
parent
dd441f8f1c
commit
4f48b3db63
14 changed files with 292 additions and 213 deletions
|
@ -21,7 +21,7 @@ use crate::output::fmt::ColorWhen;
|
|||
use crate::output::{Help, Usage};
|
||||
use crate::parse::errors::Result as ClapResult;
|
||||
use crate::parse::{ArgMatcher, ArgMatches, Parser};
|
||||
use crate::util::{Key, HELP_HASH, VERSION_HASH};
|
||||
use crate::util::{FnvHash, HELP_HASH, VERSION_HASH};
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
|
||||
type Id = u64;
|
||||
|
@ -980,7 +980,7 @@ impl<'b> App<'b> {
|
|||
pub fn mut_arg<T, F>(mut self, arg_id: T, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(Arg<'b>) -> Arg<'b>,
|
||||
T: Key + Into<&'b str>,
|
||||
T: FnvHash + Into<&'b str>,
|
||||
{
|
||||
let id = arg_id.key();
|
||||
let a = self.args.remove_by_name(id).unwrap_or_else(|| Arg {
|
||||
|
@ -1511,16 +1511,11 @@ impl<'b> App<'b> {
|
|||
$sc.max_w = $_self.max_w;
|
||||
}
|
||||
{
|
||||
for a in $_self
|
||||
.args
|
||||
.args
|
||||
.iter()
|
||||
.filter(|a| a.global)
|
||||
{
|
||||
$sc.args.push(a.clone());
|
||||
}
|
||||
for a in $_self.args.args.iter().filter(|a| a.global) {
|
||||
$sc.args.push(a.clone());
|
||||
}
|
||||
}
|
||||
}}
|
||||
}};
|
||||
}
|
||||
|
||||
debugln!("App::_propagate:{}", self.name);
|
||||
|
@ -1532,14 +1527,18 @@ impl<'b> App<'b> {
|
|||
sc._propagate(prop);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Propagation::To(id) => {
|
||||
let mut sc = self.subcommands.iter_mut().find(|sc| sc.id == id).expect(INTERNAL_ERROR_MSG);
|
||||
let mut sc = self
|
||||
.subcommands
|
||||
.iter_mut()
|
||||
.find(|sc| sc.id == id)
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
propagate_subcmd!(self, sc);
|
||||
},
|
||||
}
|
||||
Propagation::None => {
|
||||
return;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pub(crate) struct Alias<'help> {
|
||||
pub struct Alias<'help> {
|
||||
name: &'help str,
|
||||
vis: bool,
|
||||
}
|
||||
|
|
|
@ -1,88 +1,100 @@
|
|||
use crate::INTERNAL_ERR_MSG;
|
||||
use crate::build::Alias;
|
||||
|
||||
#[derive(Default)]
|
||||
struct SwitchData<'help> {
|
||||
pub struct Key<'help> {
|
||||
kind: KeyKind<'help>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SwitchData<'help> {
|
||||
longs: Vec<Alias<'help>>,
|
||||
short: Option<char>,
|
||||
}
|
||||
|
||||
pub(crate) enum ArgKey<'help> {
|
||||
pub(crate) enum KeyKind<'help> {
|
||||
Unset,
|
||||
Index(usize),
|
||||
Switch(SwitchData),
|
||||
Switch(SwitchData<'help>),
|
||||
}
|
||||
|
||||
impl Default for ArgKey<'help> {
|
||||
fn default() -> Self {
|
||||
ArgKey::Unset
|
||||
}
|
||||
impl<'help> Default for KeyKind<'help> {
|
||||
fn default() -> Self { KeyKind::Unset }
|
||||
}
|
||||
|
||||
impl<'help> ArgKey {
|
||||
fn long(&mut self, l: &'help str) {
|
||||
match *self {
|
||||
ArgKey::Unset => *self = ArgKey::Switch(SwitchData::default()),
|
||||
ArgKey::Index => panic!("You cannot add both an index and switch (short or long) to an Arg"),
|
||||
_ => (),
|
||||
}
|
||||
impl<'help> Key<'help> {
|
||||
fn set_short(&mut self, c: char) { self.switch_mut().short = Some(c); }
|
||||
fn add_long(&mut self, l: &'help str) {
|
||||
self.switch_mut()
|
||||
.expect(INTERNAL_ERR_MSG)
|
||||
.longs
|
||||
.push(Alias::visible(l.trim_left_matches(|c| c == '-')));
|
||||
}
|
||||
fn longs(&mut self, longs: &[&'help str]) {
|
||||
fn add_longs(&mut self, longs: &[&'help str]) {
|
||||
for l in longs {
|
||||
self.long(l);
|
||||
}
|
||||
}
|
||||
fn hidden_long(&mut self, l: &'help str) {
|
||||
fn add_hidden_long(&mut self, l: &'help str) {
|
||||
self.switch_mut()
|
||||
.longs
|
||||
.push(Alias::hidden(l.trim_left_matches(|c| c == '-')));
|
||||
}
|
||||
fn hidden_longs(&mut self, longs: &[&'help str]) {
|
||||
fn add_hidden_longs(&mut self, longs: &[&'help str]) {
|
||||
for l in longs {
|
||||
self.switch_mut()
|
||||
.longs
|
||||
.push(Alias::hidden(l.trim_left_matches(|c| c == '-')));
|
||||
}
|
||||
}
|
||||
fn has_index(&self) -> bool {
|
||||
use ArgKey::*;
|
||||
match *self {
|
||||
Index(_) => true,
|
||||
Switch(_) => false,
|
||||
fn set_index(&mut self, i: usize) {
|
||||
assert!(i > 0, "Argument index cannot be zero (0)");
|
||||
self.kind = KeyKind::Index(i);
|
||||
}
|
||||
fn has_index(&self) -> bool { self.index().is_some() }
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `*self != KeyKind::Index`
|
||||
fn index(&self) -> usize {
|
||||
use KeyKind::*;
|
||||
match self.kind {
|
||||
Index(i) => i,
|
||||
_ => panic!("Argument is not positional"),
|
||||
}
|
||||
}
|
||||
fn index(&self) -> Option<&usize>> {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `*self != KeyKind::Index`
|
||||
fn index_mut(&mut self) -> usize {
|
||||
use KeyKind::*;
|
||||
match *self {
|
||||
Index(i) => Some(i),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn index_mut(&mut self) -> Option<&mut usize> {
|
||||
match *self {
|
||||
Index(i) => Some(i),
|
||||
_ => None,
|
||||
Index(i) => i,
|
||||
_ => panic!("Argument is not positional"),
|
||||
}
|
||||
}
|
||||
fn has_switch(&self) -> bool {
|
||||
use ArgKey::*;
|
||||
use KeyKind::*;
|
||||
match *self {
|
||||
Index(_) => false,
|
||||
Switch(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
fn switch(&self) -> Option<&SwitchData<'help>> {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `*self != KeyKind::Switch`
|
||||
fn switch(&self) -> &SwitchData<'help> {
|
||||
use KeyKind::*;
|
||||
match *self {
|
||||
Switch(s) => Some(s),
|
||||
_ => None,
|
||||
Switch(s) => s,
|
||||
_ => panic!("Argument has no switch"),
|
||||
}
|
||||
}
|
||||
fn switch_mut(&mut self) -> Option<&mut SwitchData<'help>> {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `*self != KeyKind::Switch`
|
||||
fn switch_mut(&mut self) -> &mut SwitchData<'help> {
|
||||
use KeyKind::*;
|
||||
match *self {
|
||||
Switch(s) => Some(s),
|
||||
_ => None,
|
||||
Switch(s) => s,
|
||||
_ => panic!("Argument has no switch"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::build::arg::Alias;
|
||||
|
||||
pub(crate) struct Long<'help> {
|
||||
aliases: Vec<Alias<'help>>,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
mod alias;
|
||||
mod key;
|
||||
mod long;
|
||||
mod settings;
|
||||
|
||||
pub use self::alias::Alias;
|
||||
pub use self::key::{Key, SwitchData};
|
||||
pub use self::settings::{ArgFlags, ArgSettings};
|
||||
|
||||
// Std
|
||||
|
@ -18,9 +24,8 @@ use crate::util::VecMap;
|
|||
use yaml_rust;
|
||||
|
||||
// Internal
|
||||
use crate::build::arg::{ArgKey, SwitchData};
|
||||
use crate::build::UsageParser;
|
||||
use crate::util::Key;
|
||||
use crate::util::FnvHash;
|
||||
#[cfg(any(target_os = "windows", target_arch = "wasm32"))]
|
||||
use crate::util::OsStrExt3;
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
|
@ -127,14 +132,14 @@ pub struct Arg<'help> {
|
|||
pub val_names: Option<VecMap<&'help str>>,
|
||||
|
||||
// switch
|
||||
pub key: ArgKey<'help>,
|
||||
pub key: Key<'help>,
|
||||
}
|
||||
|
||||
impl<'help> Arg<'help> {
|
||||
/// @TODO @p2 @docs @v3-beta1: Write Docs
|
||||
pub fn new<T: Key>(t: T) -> Self {
|
||||
pub fn new<T: FnvHash>(t: T) -> Self {
|
||||
Arg {
|
||||
id: t.key(),
|
||||
id: t.fnv_hash(),
|
||||
disp_ord: 999,
|
||||
unified_ord: 999,
|
||||
..Default::default()
|
||||
|
@ -159,7 +164,7 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
pub fn with_name(n: &'help str) -> Self {
|
||||
Arg {
|
||||
id: n.key(),
|
||||
id: n.fnv_hash(),
|
||||
name: n,
|
||||
disp_ord: 999,
|
||||
unified_ord: 999,
|
||||
|
@ -280,7 +285,7 @@ impl<'help> Arg<'help> {
|
|||
/// ```
|
||||
/// [`short`]: ./struct.Arg.html#method.short
|
||||
pub fn short(mut self, s: char) -> Self {
|
||||
self.key.short(s);
|
||||
self.key.set_short(s);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -320,7 +325,7 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(m.is_present("cfg"));
|
||||
/// ```
|
||||
pub fn long(mut self, l: &'help str) -> Self {
|
||||
self.key.long(l);
|
||||
self.key.add_long(l);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -342,7 +347,7 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
/// [`App::aliases`]: ./struct.Arg.html#method.aliases
|
||||
pub fn longs(mut self, names: &[&'help str]) -> Self {
|
||||
self.key.longs(names);
|
||||
self.key.add_longs(names);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -372,7 +377,7 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
/// [long]: ./struct.Arg.html#method.long
|
||||
pub fn hidden_long<S: Into<&'help str>>(mut self, name: S) -> Self {
|
||||
self.key.hidden_long(name);
|
||||
self.key.add_hidden_long(name);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -396,7 +401,8 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
/// [hidden longs]: ./struct.Arg.html#method.hidden_long
|
||||
pub fn hidden_longs(mut self, names: &[&'help str]) -> Self {
|
||||
self.key.hidden_longs(names): self
|
||||
self.key.add_hidden_longs(names);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the short help text of the argument that will be displayed to the user when they print
|
||||
|
@ -581,8 +587,8 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::required_unless`]: ./struct.Arg.html#method.required_unless
|
||||
/// [`Arg::required`]: ./struct.Arg.html#method.required
|
||||
/// [`Arg::required_unless(name)`]: ./struct.Arg.html#method.required_unless
|
||||
pub fn required_unless<T: Key>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.key();
|
||||
pub fn required_unless<T: FnvHash>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.fnv_hash();
|
||||
if let Some(ref mut vec) = self.r_unless {
|
||||
vec.push(name);
|
||||
} else {
|
||||
|
@ -657,10 +663,10 @@ impl<'help> Arg<'help> {
|
|||
pub fn required_unless_all(mut self, names: &[&str]) -> Self {
|
||||
if let Some(ref mut vec) = self.r_unless {
|
||||
for s in names {
|
||||
vec.push(s.key());
|
||||
vec.push(s.fnv_hash());
|
||||
}
|
||||
} else {
|
||||
self.r_unless = Some(names.iter().map(Key::key).collect());
|
||||
self.r_unless = Some(names.iter().map(FnvHash::id).collect());
|
||||
}
|
||||
self.setting(ArgSettings::RequiredUnlessAll)
|
||||
}
|
||||
|
@ -732,10 +738,10 @@ impl<'help> Arg<'help> {
|
|||
pub fn required_unless_one(mut self, names: &[&str]) -> Self {
|
||||
if let Some(ref mut vec) = self.r_unless {
|
||||
for s in names {
|
||||
vec.push(s.key());
|
||||
vec.push(s.fnv_hash());
|
||||
}
|
||||
} else {
|
||||
self.r_unless = Some(names.iter().map(Key::key).collect());
|
||||
self.r_unless = Some(names.iter().map(FnvHash::id).collect());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -777,8 +783,8 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(res.is_err());
|
||||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::ArgumentConflict);
|
||||
/// ```
|
||||
pub fn conflicts_with<T: Key>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.key();
|
||||
pub fn conflicts_with<T: FnvHash>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.fnv_hash();
|
||||
if let Some(ref mut vec) = self.blacklist {
|
||||
vec.push(name);
|
||||
} else {
|
||||
|
@ -831,10 +837,10 @@ impl<'help> Arg<'help> {
|
|||
pub fn conflicts_with_all(mut self, names: &[&str]) -> Self {
|
||||
if let Some(ref mut vec) = self.blacklist {
|
||||
for s in names {
|
||||
vec.push(s.key());
|
||||
vec.push(s.fnv_hash());
|
||||
}
|
||||
} else {
|
||||
self.blacklist = Some(names.iter().map(Key::key).collect());
|
||||
self.blacklist = Some(names.iter().map(FnvHash::id).collect());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -940,8 +946,8 @@ impl<'help> Arg<'help> {
|
|||
/// ```
|
||||
/// [`Multiple*`]: ./enum.ArgSettings.html#variant.MultipleValues
|
||||
/// [`UseValueDelimiter`]: ./enum.ArgSettings.html#variant.UseValueDelimiter
|
||||
pub fn overrides_with<T: Key>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.key();
|
||||
pub fn overrides_with<T: FnvHash>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.fnv_hash();
|
||||
if let Some(ref mut vec) = self.overrides {
|
||||
vec.push(name);
|
||||
} else {
|
||||
|
@ -977,13 +983,13 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(!m.is_present("debug"));
|
||||
/// assert!(!m.is_present("flag"));
|
||||
/// ```
|
||||
pub fn overrides_with_all<T: Key>(mut self, names: &[T]) -> Self {
|
||||
pub fn overrides_with_all<T: FnvHash>(mut self, names: &[T]) -> Self {
|
||||
if let Some(ref mut vec) = self.overrides {
|
||||
for s in names {
|
||||
vec.push(s.key());
|
||||
vec.push(s.fnv_hash());
|
||||
}
|
||||
} else {
|
||||
self.overrides = Some(names.iter().map(Key::key).collect());
|
||||
self.overrides = Some(names.iter().map(FnvHash::id).collect());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1043,8 +1049,8 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::requires(name)`]: ./struct.Arg.html#method.requires
|
||||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
pub fn requires<T: Key>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.key();
|
||||
pub fn requires<T: FnvHash>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.fnv_hash();
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
vec.push((None, name));
|
||||
} else {
|
||||
|
@ -1114,8 +1120,8 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::requires(name)`]: ./struct.Arg.html#method.requires
|
||||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
pub fn requires_if<T: Key>(mut self, val: &'help str, arg_id: T) -> Self {
|
||||
let arg = arg_id.key();
|
||||
pub fn requires_if<T: FnvHash>(mut self, val: &'help str, arg_id: T) -> Self {
|
||||
let arg = arg_id.fnv_hash();
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
vec.push((Some(val), arg));
|
||||
} else {
|
||||
|
@ -1175,15 +1181,15 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::requires(name)`]: ./struct.Arg.html#method.requires
|
||||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
pub fn requires_ifs<T: Key>(mut self, ifs: &[(&'help str, T)]) -> Self {
|
||||
pub fn requires_ifs<T: FnvHash>(mut self, ifs: &[(&'help str, T)]) -> Self {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
for (val, arg) in ifs {
|
||||
vec.push((Some(val), arg.key()));
|
||||
vec.push((Some(val), arg.fnv_hash()));
|
||||
}
|
||||
} else {
|
||||
let mut vec = vec![];
|
||||
for (val, arg) in ifs {
|
||||
vec.push((Some(*val), arg.key()));
|
||||
vec.push((Some(*val), arg.fnv_hash()));
|
||||
}
|
||||
self.requires = Some(vec);
|
||||
}
|
||||
|
@ -1253,8 +1259,8 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::requires(name)`]: ./struct.Arg.html#method.requires
|
||||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [required]: ./struct.Arg.html#method.required
|
||||
pub fn required_if<T: Key>(mut self, arg_id: T, val: &'help str) -> Self {
|
||||
let arg = arg_id.key();
|
||||
pub fn required_if<T: FnvHash>(mut self, arg_id: T, val: &'help str) -> Self {
|
||||
let arg = arg_id.fnv_hash();
|
||||
if let Some(ref mut vec) = self.r_ifs {
|
||||
vec.push((arg, val));
|
||||
} else {
|
||||
|
@ -1343,15 +1349,15 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::requires(name)`]: ./struct.Arg.html#method.requires
|
||||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [required]: ./struct.Arg.html#method.required
|
||||
pub fn required_ifs<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self {
|
||||
pub fn required_ifs<T: FnvHash>(mut self, ifs: &[(T, &'help str)]) -> Self {
|
||||
if let Some(ref mut vec) = self.r_ifs {
|
||||
for r_if in ifs {
|
||||
vec.push((r_if.0.key(), r_if.1));
|
||||
vec.push((r_if.0.fnv_hash(), r_if.1));
|
||||
}
|
||||
} else {
|
||||
let mut vec = vec![];
|
||||
for r_if in ifs {
|
||||
vec.push((r_if.0.key(), r_if.1));
|
||||
vec.push((r_if.0.fnv_hash(), r_if.1));
|
||||
}
|
||||
self.r_ifs = Some(vec);
|
||||
}
|
||||
|
@ -1420,15 +1426,15 @@ impl<'help> Arg<'help> {
|
|||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
/// [`Arg::requires_all(&[arg, arg2])`]: ./struct.Arg.html#method.requires_all
|
||||
pub fn requires_all<T: Key>(mut self, names: &[T]) -> Self {
|
||||
pub fn requires_all<T: FnvHash>(mut self, names: &[T]) -> Self {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
for s in names {
|
||||
vec.push((None, s.key()));
|
||||
vec.push((None, s.fnv_hash()));
|
||||
}
|
||||
} else {
|
||||
let mut vec = vec![];
|
||||
for s in names {
|
||||
vec.push((None, s.key()));
|
||||
vec.push((None, s.fnv_hash()));
|
||||
}
|
||||
self.requires = Some(vec);
|
||||
}
|
||||
|
@ -1483,7 +1489,7 @@ impl<'help> Arg<'help> {
|
|||
/// [`App`]: ./struct.App.html
|
||||
/// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html
|
||||
pub fn index(mut self, idx: u64) -> Self {
|
||||
self.key.index = ArgKey::Index(idx);
|
||||
self.key.set_index(idx);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -1690,8 +1696,8 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(m.is_present("mode"));
|
||||
/// ```
|
||||
/// [`ArgGroup`]: ./struct.ArgGroup.html
|
||||
pub fn group<T: Key>(mut self, group_id: T) -> Self {
|
||||
let name = group_id.key();
|
||||
pub fn group<T: FnvHash>(mut self, group_id: T) -> Self {
|
||||
let name = group_id.fnv_hash();
|
||||
if let Some(ref mut vec) = self.groups {
|
||||
vec.push(name);
|
||||
} else {
|
||||
|
@ -1731,13 +1737,13 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(m.is_present("verbosity"));
|
||||
/// ```
|
||||
/// [`ArgGroup`]: ./struct.ArgGroup.html
|
||||
pub fn groups<T: Key>(mut self, group_ids: &[T]) -> Self {
|
||||
pub fn groups<T: FnvHash>(mut self, group_ids: &[T]) -> Self {
|
||||
if let Some(ref mut vec) = self.groups {
|
||||
for s in group_ids {
|
||||
vec.push(s.key());
|
||||
vec.push(s.fnv_hash());
|
||||
}
|
||||
} else {
|
||||
self.groups = Some(group_ids.iter().map(Key::key).collect());
|
||||
self.groups = Some(group_ids.iter().map(FnvHash::id).collect());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -2342,7 +2348,7 @@ impl<'help> Arg<'help> {
|
|||
/// ```
|
||||
/// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
|
||||
/// [`Arg::default_value`]: ./struct.Arg.html#method.default_value
|
||||
pub fn default_value_if<T: Key>(
|
||||
pub fn default_value_if<T: FnvHash>(
|
||||
self,
|
||||
arg_id: T,
|
||||
val: Option<&'help str>,
|
||||
|
@ -2359,13 +2365,13 @@ impl<'help> Arg<'help> {
|
|||
/// only using [`OsStr`]s instead.
|
||||
/// [`Arg::default_value_if`]: ./struct.Arg.html#method.default_value_if
|
||||
/// [`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
|
||||
pub fn default_value_if_os<T: Key>(
|
||||
pub fn default_value_if_os<T: FnvHash>(
|
||||
mut self,
|
||||
arg_id: T,
|
||||
val: Option<&'help OsStr>,
|
||||
default: &'help OsStr,
|
||||
) -> Self {
|
||||
let arg = arg_id.key();
|
||||
let arg = arg_id.fnv_hash();
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
if let Some(ref mut vm) = self.default_vals_ifs {
|
||||
let l = vm.len();
|
||||
|
@ -2462,7 +2468,7 @@ impl<'help> Arg<'help> {
|
|||
/// ```
|
||||
/// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
|
||||
/// [`Arg::default_value`]: ./struct.Arg.html#method.default_value
|
||||
pub fn default_value_ifs<T: Key>(
|
||||
pub fn default_value_ifs<T: FnvHash>(
|
||||
mut self,
|
||||
ifs: &[(T, Option<&'help str>, &'help str)],
|
||||
) -> Self {
|
||||
|
@ -2481,12 +2487,12 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::default_value_ifs`]: ./struct.Arg.html#method.default_value_ifs
|
||||
/// [`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
|
||||
#[cfg_attr(feature = "lints", allow(explicit_counter_loop))]
|
||||
pub fn default_value_ifs_os<T: Key>(
|
||||
pub fn default_value_ifs_os<T: FnvHash>(
|
||||
mut self,
|
||||
ifs: &[(T, Option<&'help OsStr>, &'help OsStr)],
|
||||
) -> Self {
|
||||
for (arg, val, default) in ifs {
|
||||
self = self.default_value_if_os(arg.key(), *val, default);
|
||||
self = self.default_value_if_os(arg.fnv_hash(), *val, default);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::fmt::{Debug, Formatter, Result};
|
|||
use yaml_rust;
|
||||
|
||||
// Internal
|
||||
use crate::util::Key;
|
||||
use crate::util::FnvHash;
|
||||
|
||||
type Id = u64;
|
||||
|
||||
|
@ -107,7 +107,7 @@ impl<'a> ArgGroup<'a> {
|
|||
}
|
||||
}
|
||||
/// @TODO @p2 @docs @v3-beta1: Write Docs
|
||||
pub fn new<T: Key>(id: T) -> Self { ArgGroup::_with_id(id.key()) }
|
||||
pub fn new<T: FnvHash>(id: T) -> Self { ArgGroup::_with_id(id.fnv_hash()) }
|
||||
/// Creates a new instance of `ArgGroup` using a unique string name. The name will be used to
|
||||
/// get values from the group or refer to the group inside of conflict and requirement rules.
|
||||
///
|
||||
|
@ -120,7 +120,7 @@ impl<'a> ArgGroup<'a> {
|
|||
/// ```
|
||||
pub fn with_name(n: &'a str) -> Self {
|
||||
ArgGroup {
|
||||
id: n.key(),
|
||||
id: n.fnv_hash(),
|
||||
name: n,
|
||||
..ArgGroup::default()
|
||||
}
|
||||
|
@ -166,8 +166,8 @@ impl<'a> ArgGroup<'a> {
|
|||
/// ```
|
||||
/// [argument]: ./struct.Arg.html
|
||||
#[cfg_attr(feature = "lints", allow(should_assert_eq))]
|
||||
pub fn arg<T: Key>(mut self, arg_id: T) -> Self {
|
||||
self.args.push(arg_id.key());
|
||||
pub fn arg<T: FnvHash>(mut self, arg_id: T) -> Self {
|
||||
self.args.push(arg_id.fnv_hash());
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ impl<'a> ArgGroup<'a> {
|
|||
/// assert!(m.is_present("flag"));
|
||||
/// ```
|
||||
/// [arguments]: ./struct.Arg.html
|
||||
pub fn args<T: Key>(mut self, ns: &[T]) -> Self {
|
||||
pub fn args<T: FnvHash>(mut self, ns: &[T]) -> Self {
|
||||
for n in ns {
|
||||
self = self.arg(n);
|
||||
}
|
||||
|
@ -312,8 +312,8 @@ impl<'a> ArgGroup<'a> {
|
|||
/// ```
|
||||
/// [required group]: ./struct.ArgGroup.html#method.required
|
||||
/// [argument requirement rules]: ./struct.Arg.html#method.requires
|
||||
pub fn requires<T: Key>(mut self, id: T) -> Self {
|
||||
let arg_id = id.key();
|
||||
pub fn requires<T: FnvHash>(mut self, id: T) -> Self {
|
||||
let arg_id = id.fnv_hash();
|
||||
if let Some(ref mut reqs) = self.requires {
|
||||
reqs.push(arg_id);
|
||||
} else {
|
||||
|
@ -388,8 +388,8 @@ impl<'a> ArgGroup<'a> {
|
|||
/// assert_eq!(err.kind, ErrorKind::ArgumentConflict);
|
||||
/// ```
|
||||
/// [argument exclusion rules]: ./struct.Arg.html#method.conflicts_with
|
||||
pub fn conflicts_with<T: Key>(mut self, id: T) -> Self {
|
||||
let arg_id = id.key();
|
||||
pub fn conflicts_with<T: FnvHash>(mut self, id: T) -> Self {
|
||||
let arg_id = id.fnv_hash();
|
||||
if let Some(ref mut confs) = self.conflicts {
|
||||
confs.push(arg_id);
|
||||
} else {
|
||||
|
@ -519,7 +519,7 @@ impl<'a> From<&'a yaml_rust::yaml::Hash> for ArgGroup<'a> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::ArgGroup;
|
||||
use super::Key;
|
||||
use super::FnvHash;
|
||||
#[cfg(feature = "yaml")]
|
||||
use yaml_rust::YamlLoader;
|
||||
|
||||
|
@ -537,9 +537,24 @@ mod test {
|
|||
.requires_all(&["r2", "r3"])
|
||||
.requires("r4");
|
||||
|
||||
let args = vec!["a1".key(), "a4".key(), "a2".key(), "a3".key()];
|
||||
let reqs = vec!["r1".key(), "r2".key(), "r3".key(), "r4".key()];
|
||||
let confs = vec!["c1".key(), "c2".key(), "c3".key(), "c4".key()];
|
||||
let args = vec![
|
||||
"a1".fnv_hash(),
|
||||
"a4".fnv_hash(),
|
||||
"a2".fnv_hash(),
|
||||
"a3".fnv_hash(),
|
||||
];
|
||||
let reqs = vec![
|
||||
"r1".fnv_hash(),
|
||||
"r2".fnv_hash(),
|
||||
"r3".fnv_hash(),
|
||||
"r4".fnv_hash(),
|
||||
];
|
||||
let confs = vec![
|
||||
"c1".fnv_hash(),
|
||||
"c2".fnv_hash(),
|
||||
"c3".fnv_hash(),
|
||||
"c4".fnv_hash(),
|
||||
];
|
||||
|
||||
assert_eq!(g.args, args);
|
||||
assert_eq!(g.requires, Some(reqs));
|
||||
|
@ -560,9 +575,24 @@ mod test {
|
|||
.requires_all(&["r2", "r3"])
|
||||
.requires("r4");
|
||||
|
||||
let args = vec!["a1".key(), "a4".key(), "a2".key(), "a3".key()];
|
||||
let reqs = vec!["r1".key(), "r2".key(), "r3".key(), "r4".key()];
|
||||
let confs = vec!["c1".key(), "c2".key(), "c3".key(), "c4".key()];
|
||||
let args = vec![
|
||||
"a1".fnv_hash(),
|
||||
"a4".fnv_hash(),
|
||||
"a2".fnv_hash(),
|
||||
"a3".fnv_hash(),
|
||||
];
|
||||
let reqs = vec![
|
||||
"r1".fnv_hash(),
|
||||
"r2".fnv_hash(),
|
||||
"r3".fnv_hash(),
|
||||
"r4".fnv_hash(),
|
||||
];
|
||||
let confs = vec![
|
||||
"c1".fnv_hash(),
|
||||
"c2".fnv_hash(),
|
||||
"c3".fnv_hash(),
|
||||
"c4".fnv_hash(),
|
||||
];
|
||||
|
||||
let debug_str = format!(
|
||||
"{{\n\
|
||||
|
@ -594,9 +624,24 @@ mod test {
|
|||
.requires_all(&["r2", "r3"])
|
||||
.requires("r4");
|
||||
|
||||
let args = vec!["a1".key(), "a4".key(), "a2".key(), "a3".key()];
|
||||
let reqs = vec!["r1".key(), "r2".key(), "r3".key(), "r4".key()];
|
||||
let confs = vec!["c1".key(), "c2".key(), "c3".key(), "c4".key()];
|
||||
let args = vec![
|
||||
"a1".fnv_hash(),
|
||||
"a4".fnv_hash(),
|
||||
"a2".fnv_hash(),
|
||||
"a3".fnv_hash(),
|
||||
];
|
||||
let reqs = vec![
|
||||
"r1".fnv_hash(),
|
||||
"r2".fnv_hash(),
|
||||
"r3".fnv_hash(),
|
||||
"r4".fnv_hash(),
|
||||
];
|
||||
let confs = vec![
|
||||
"c1".fnv_hash(),
|
||||
"c2".fnv_hash(),
|
||||
"c3".fnv_hash(),
|
||||
"c4".fnv_hash(),
|
||||
];
|
||||
|
||||
let g2 = ArgGroup::from(&g);
|
||||
assert_eq!(g2.args, args);
|
||||
|
@ -625,9 +670,24 @@ requires:
|
|||
- r4";
|
||||
let yml = &YamlLoader::load_from_str(g_yaml).expect("failed to load YAML file")[0];
|
||||
let g = ArgGroup::from_yaml(yml);
|
||||
let args = vec!["a1".key(), "a4".key(), "a2".key(), "a3".key()];
|
||||
let reqs = vec!["r1".key(), "r2".key(), "r3".key(), "r4".key()];
|
||||
let confs = vec!["c1".key(), "c2".key(), "c3".key(), "c4".key()];
|
||||
let args = vec![
|
||||
"a1".fnv_hash(),
|
||||
"a4".fnv_hash(),
|
||||
"a2".fnv_hash(),
|
||||
"a3".fnv_hash(),
|
||||
];
|
||||
let reqs = vec![
|
||||
"r1".fnv_hash(),
|
||||
"r2".fnv_hash(),
|
||||
"r3".fnv_hash(),
|
||||
"r4".fnv_hash(),
|
||||
];
|
||||
let confs = vec![
|
||||
"c1".fnv_hash(),
|
||||
"c2".fnv_hash(),
|
||||
"c3".fnv_hash(),
|
||||
"c4".fnv_hash(),
|
||||
];
|
||||
assert_eq!(g.args, args);
|
||||
assert_eq!(g.requires, Some(reqs));
|
||||
assert_eq!(g.conflicts, Some(confs));
|
||||
|
|
|
@ -8,6 +8,6 @@ mod arg_group;
|
|||
mod usage_parser;
|
||||
|
||||
pub use self::app::{App, AppFlags, AppSettings, Propagation};
|
||||
pub use self::arg::{Arg, ArgFlags, ArgKey, ArgSettings};
|
||||
pub use self::arg::{Alias, Arg, ArgFlags, ArgSettings, Key};
|
||||
pub use self::arg_group::ArgGroup;
|
||||
pub use self::usage_parser::UsageParser;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Internal
|
||||
use crate::build::{Arg, ArgSettings};
|
||||
use crate::util::{Key, VecMap};
|
||||
use crate::util::{FnvHash, VecMap};
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
|
@ -89,7 +89,7 @@ impl<'a> UsageParser<'a> {
|
|||
let name = &self.usage[self.start..self.pos];
|
||||
if self.prev == UsageToken::Unknown {
|
||||
debugln!("UsageParser::name: setting name...{}", name);
|
||||
arg.id = name.key();
|
||||
arg.id = name.fnv_hash();
|
||||
arg.name = name;
|
||||
if arg.long.is_none() && arg.short.is_none() {
|
||||
debugln!("UsageParser::name: explicit name set...");
|
||||
|
@ -146,7 +146,7 @@ impl<'a> UsageParser<'a> {
|
|||
let name = &self.usage[self.start..self.pos];
|
||||
if !self.explicit_name_set {
|
||||
debugln!("UsageParser::long: setting name...{}", name);
|
||||
arg.id = name.key();
|
||||
arg.id = name.fnv_hash();
|
||||
arg.name = name;
|
||||
}
|
||||
debugln!("UsageParser::long: setting long...{}", name);
|
||||
|
@ -164,7 +164,7 @@ impl<'a> UsageParser<'a> {
|
|||
// --long takes precedence but doesn't set self.explicit_name_set
|
||||
let name = &start[..short.len_utf8()];
|
||||
debugln!("UsageParser::short: setting name...{}", name);
|
||||
arg.id = name.key();
|
||||
arg.id = name.fnv_hash();
|
||||
arg.name = name;
|
||||
}
|
||||
self.prev = UsageToken::Short;
|
||||
|
|
|
@ -1000,9 +1000,9 @@ macro_rules! find_subcmd {
|
|||
|
||||
macro_rules! longs {
|
||||
($app:expr) => {{
|
||||
use crate::mkeymap::KeyType;
|
||||
use crate::mkeymap::MapKeyKind;
|
||||
$app.args.keys.iter().map(|x| &x.key).filter_map(|a| {
|
||||
if let KeyType::Long(v) = a {
|
||||
if let MapKeyKind::Long(v) = a {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
use bstr::{BStr, BString};
|
||||
|
||||
// Internal
|
||||
use crate::build::Arg;
|
||||
use crate::util::Key;
|
||||
use crate::build::arg::{Arg, Key};
|
||||
use crate::util::FnvHash;
|
||||
|
||||
type Id = u64;
|
||||
|
||||
|
@ -15,74 +15,74 @@ pub struct MKeyMap<'b> {
|
|||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct MapKey {
|
||||
pub key: MapKeyType,
|
||||
pub key: MapKeyKind,
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub enum MapKeyType {
|
||||
pub enum MapKeyKind {
|
||||
Id(Id),
|
||||
Short(char),
|
||||
Long(BString),
|
||||
Position(usize),
|
||||
}
|
||||
|
||||
impl MapKeyType {
|
||||
impl MapKeyKind {
|
||||
pub(crate) fn is_position(&self) -> bool {
|
||||
match *self {
|
||||
MapKeyType::Position(_) => true,
|
||||
MapKeyKind::Position(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<usize> for MapKeyType {
|
||||
impl PartialEq<usize> for MapKeyKind {
|
||||
fn eq(&self, rhs: &usize) -> bool {
|
||||
match self {
|
||||
MapKeyType::Position(i) => i == rhs,
|
||||
MapKeyKind::Position(i) => i == rhs,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Id> for MapKeyType {
|
||||
impl PartialEq<Id> for MapKeyKind {
|
||||
fn eq(&self, rhs: &Id) -> bool {
|
||||
match self {
|
||||
MapKeyType::Id(i) => i == rhs,
|
||||
MapKeyKind::Id(i) => i == rhs,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<str> for MapKeyType {
|
||||
impl PartialEq<str> for MapKeyKind {
|
||||
fn eq(&self, rhs: &str) -> bool {
|
||||
match self {
|
||||
MapKeyType::Long(ref l) => l == rhs,
|
||||
MapKeyType::Id(i) => i == rhs.key(),
|
||||
MapKeyKind::Long(ref l) => l == rhs,
|
||||
MapKeyKind::Id(i) => i == rhs.fnv_hash(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<char> for MapKeyType {
|
||||
impl PartialEq<char> for MapKeyKind {
|
||||
fn eq(&self, rhs: &char) -> bool {
|
||||
match self {
|
||||
MapKeyType::Short(c) => c == rhs,
|
||||
MapKeyKind::Short(c) => c == rhs,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for MapKeyType {
|
||||
fn from(us: usize) -> Self { MapKeyType::Position(us) }
|
||||
impl From<usize> for MapKeyKind {
|
||||
fn from(us: usize) -> Self { MapKeyKind::Position(us) }
|
||||
}
|
||||
|
||||
impl From<char> for MapKeyType {
|
||||
fn from(c: char) -> Self { MapKeyType::Short(c) }
|
||||
impl From<char> for MapKeyKind {
|
||||
fn from(c: char) -> Self { MapKeyKind::Short(c) }
|
||||
}
|
||||
|
||||
impl From<Id> for MapKeyType {
|
||||
fn from(i: Id) -> Self { MapKeyType::Id(i) }
|
||||
impl From<Id> for MapKeyKind {
|
||||
fn from(i: Id) -> Self { MapKeyKind::Id(i) }
|
||||
}
|
||||
|
||||
impl<'b> MKeyMap<'b> {
|
||||
|
@ -97,12 +97,12 @@ impl<'b> MKeyMap<'b> {
|
|||
index
|
||||
}
|
||||
|
||||
pub fn contains<K: Into<MapKeyType>>(&self, k: K) -> bool {
|
||||
pub fn contains<K: Into<MapKeyKind>>(&self, k: K) -> bool {
|
||||
let key = k.into();
|
||||
self.keys.iter().any(|x| x.key == key)
|
||||
}
|
||||
|
||||
pub fn find<K: Into<MapKeyType>>(&self, k: K) -> Option<&Arg<'b>> {
|
||||
pub fn find<K: Into<MapKeyKind>>(&self, k: K) -> Option<&Arg<'b>> {
|
||||
let key = k.into();
|
||||
self.keys
|
||||
.iter()
|
||||
|
@ -110,7 +110,7 @@ impl<'b> MKeyMap<'b> {
|
|||
.map(|mk| self.args.get(mk.index))
|
||||
}
|
||||
|
||||
pub fn remove_key<K: Into<MapKeyType>>(&mut self, k: K) {
|
||||
pub fn remove_key<K: Into<MapKeyKind>>(&mut self, k: K) {
|
||||
let key = k.into();
|
||||
let mut idx = None;
|
||||
for k in self.keys.iter() {
|
||||
|
@ -124,7 +124,7 @@ impl<'b> MKeyMap<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove<K: Into<MapKeyType>>(&mut self, k: K) -> Option<Arg<'b>> {
|
||||
pub fn remove<K: Into<MapKeyKind>>(&mut self, k: K) -> Option<Arg<'b>> {
|
||||
let key = k.into();
|
||||
let mut idx = None;
|
||||
for k in self.keys.iter() {
|
||||
|
@ -149,15 +149,15 @@ impl<'b> MKeyMap<'b> {
|
|||
for k in get_keys(arg) {
|
||||
self.keys.push(MapKey { key: k, index: i });
|
||||
}
|
||||
if arg.arg_key() == ArgKey::Unset {
|
||||
a.index(counter);
|
||||
if arg.key() == Key::Unset {
|
||||
arg.index(counter);
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_by_name(&self, name: &str) -> Option<&Arg<'b>> {
|
||||
let key: MapKeyType = name.key().into();
|
||||
let key: MapKeyKind = name.key().into();
|
||||
self.keys
|
||||
.iter()
|
||||
.find(|x| x.key == key)
|
||||
|
@ -165,7 +165,7 @@ impl<'b> MKeyMap<'b> {
|
|||
}
|
||||
|
||||
pub fn remove_by_name(&mut self, name: &str) -> Option<Arg<'b>> {
|
||||
let key: MapKeyType = name.key().into();
|
||||
let key: MapKeyKind = name.key().into();
|
||||
let mut index = None;
|
||||
for k in self.keys.iter() {
|
||||
if k.key == key {
|
||||
|
@ -184,7 +184,7 @@ impl<'b> MKeyMap<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_keys(arg: &Arg) -> Vec<MapKeyType> {
|
||||
fn get_keys(arg: &Arg) -> Vec<MapKeyKind> {
|
||||
let mut keys = vec![arg.id.into()];
|
||||
if let Some(index) = arg.index {
|
||||
keys.push(index.into());
|
||||
|
@ -203,7 +203,7 @@ fn get_keys(arg: &Arg) -> Vec<MapKeyType> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use self::MapKeyType::*;
|
||||
use self::MapKeyKind::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -9,7 +9,7 @@ use indexmap::IndexMap;
|
|||
|
||||
// Internal
|
||||
use crate::parse::{MatchedArg, SubCommand};
|
||||
use crate::util::Key;
|
||||
use crate::util::FnvHash;
|
||||
use crate::INVALID_UTF8;
|
||||
|
||||
type Id = u64;
|
||||
|
@ -113,8 +113,8 @@ impl ArgMatches {
|
|||
/// [positional]: ./struct.Arg.html#method.index
|
||||
/// [`ArgMatches::values_of`]: ./struct.ArgMatches.html#method.values_of
|
||||
/// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html
|
||||
pub fn value_of<T: Key>(&self, id: T) -> Option<&str> {
|
||||
if let Some(arg) = self.args.get(&id.key()) {
|
||||
pub fn value_of<T: FnvHash>(&self, id: T) -> Option<&str> {
|
||||
if let Some(arg) = self.args.get(&id.fnv_hash()) {
|
||||
if let Some(v) = arg.vals.get(0) {
|
||||
return Some(v.to_str().expect(INVALID_UTF8));
|
||||
}
|
||||
|
@ -145,8 +145,8 @@ impl ArgMatches {
|
|||
/// assert_eq!(&*m.value_of_lossy("arg").unwrap(), "Hi \u{FFFD}!");
|
||||
/// ```
|
||||
/// [`Arg::values_of_lossy`]: ./struct.ArgMatches.html#method.values_of_lossy
|
||||
pub fn value_of_lossy<T: Key>(&self, id: T) -> Option<Cow<'_, str>> {
|
||||
if let Some(arg) = self.args.get(&id.key()) {
|
||||
pub fn value_of_lossy<T: FnvHash>(&self, id: T) -> Option<Cow<'_, str>> {
|
||||
if let Some(arg) = self.args.get(&id.fnv_hash()) {
|
||||
if let Some(v) = arg.vals.get(0) {
|
||||
return Some(v.to_string_lossy());
|
||||
}
|
||||
|
@ -181,9 +181,9 @@ impl ArgMatches {
|
|||
/// ```
|
||||
/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
|
||||
/// [`ArgMatches::values_of_os`]: ./struct.ArgMatches.html#method.values_of_os
|
||||
pub fn value_of_os<T: Key>(&self, id: T) -> Option<&OsStr> {
|
||||
pub fn value_of_os<T: FnvHash>(&self, id: T) -> Option<&OsStr> {
|
||||
self.args
|
||||
.get(&id.key())
|
||||
.get(&id.fnv_hash())
|
||||
.and_then(|arg| arg.vals.get(0).map(OsString::as_os_str))
|
||||
}
|
||||
|
||||
|
@ -212,8 +212,8 @@ impl ArgMatches {
|
|||
/// ```
|
||||
/// [`Values`]: ./struct.Values.html
|
||||
/// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
|
||||
pub fn values_of<T: Key>(&self, id: T) -> Option<Values<'_>> {
|
||||
self.args.get(&id.key()).map(|arg| {
|
||||
pub fn values_of<T: FnvHash>(&self, id: T) -> Option<Values<'_>> {
|
||||
self.args.get(&id.fnv_hash()).map(|arg| {
|
||||
fn to_str_slice(o: &OsString) -> &str { o.to_str().expect(INVALID_UTF8) }
|
||||
let to_str_slice: fn(&OsString) -> &str = to_str_slice; // coerce to fn pointer
|
||||
|
||||
|
@ -247,8 +247,8 @@ impl ArgMatches {
|
|||
/// assert_eq!(&itr.next().unwrap()[..], "\u{FFFD}!");
|
||||
/// assert_eq!(itr.next(), None);
|
||||
/// ```
|
||||
pub fn values_of_lossy<T: Key>(&self, id: T) -> Option<Vec<String>> {
|
||||
self.args.get(&id.key()).map(|arg| {
|
||||
pub fn values_of_lossy<T: FnvHash>(&self, id: T) -> Option<Vec<String>> {
|
||||
self.args.get(&id.fnv_hash()).map(|arg| {
|
||||
arg.vals
|
||||
.iter()
|
||||
.map(|v| v.to_string_lossy().into_owned())
|
||||
|
@ -287,11 +287,11 @@ impl ArgMatches {
|
|||
/// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
|
||||
/// [`OsString`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html
|
||||
/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
|
||||
pub fn values_of_os<'a, T: Key>(&'a self, id: T) -> Option<OsValues<'a>> {
|
||||
pub fn values_of_os<'a, T: FnvHash>(&'a self, id: T) -> Option<OsValues<'a>> {
|
||||
fn to_str_slice(o: &OsString) -> &OsStr { &*o }
|
||||
let to_str_slice: fn(&'a OsString) -> &'a OsStr = to_str_slice; // coerce to fn pointer
|
||||
|
||||
self.args.get(&id.key()).map(|arg| OsValues {
|
||||
self.args.get(&id.fnv_hash()).map(|arg| OsValues {
|
||||
iter: arg.vals.iter().map(to_str_slice),
|
||||
})
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ impl ArgMatches {
|
|||
///
|
||||
/// assert!(m.is_present("debug"));
|
||||
/// ```
|
||||
pub fn is_present<T: Key>(&self, id: T) -> bool { self._id_is_present(id.key()) }
|
||||
pub fn is_present<T: FnvHash>(&self, id: T) -> bool { self._id_is_present(id.fnv_hash()) }
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _id_is_present(&self, arg_id: Id) -> bool {
|
||||
|
@ -362,8 +362,8 @@ impl ArgMatches {
|
|||
/// assert_eq!(m.occurrences_of("debug"), 3);
|
||||
/// assert_eq!(m.occurrences_of("flag"), 1);
|
||||
/// ```
|
||||
pub fn occurrences_of<T: Key>(&self, id: T) -> u64 {
|
||||
self.args.get(&id.key()).map_or(0, |a| a.occurs)
|
||||
pub fn occurrences_of<T: FnvHash>(&self, id: T) -> u64 {
|
||||
self.args.get(&id.fnv_hash()).map_or(0, |a| a.occurs)
|
||||
}
|
||||
|
||||
/// Gets the starting index of the argument in respect to all other arguments. Indices are
|
||||
|
@ -496,8 +496,8 @@ impl ArgMatches {
|
|||
/// ```
|
||||
/// [`ArgMatches`]: ./struct.ArgMatches.html
|
||||
/// [delimiter]: ./struct.Arg.html#method.value_delimiter
|
||||
pub fn index_of<T: Key>(&self, name: T) -> Option<usize> {
|
||||
if let Some(arg) = self.args.get(&name.key()) {
|
||||
pub fn index_of<T: FnvHash>(&self, name: T) -> Option<usize> {
|
||||
if let Some(arg) = self.args.get(&name.fnv_hash()) {
|
||||
if let Some(i) = arg.indices.get(0) {
|
||||
return Some(*i);
|
||||
}
|
||||
|
@ -578,8 +578,8 @@ impl ArgMatches {
|
|||
/// [`ArgMatches`]: ./struct.ArgMatches.html
|
||||
/// [`ArgMatches::index_of`]: ./struct.ArgMatches.html#method.index_of
|
||||
/// [delimiter]: ./struct.Arg.html#method.value_delimiter
|
||||
pub fn indices_of<T: Key>(&self, id: T) -> Option<Indices<'_>> {
|
||||
self.args.get(&id.key()).map(|arg| Indices {
|
||||
pub fn indices_of<T: FnvHash>(&self, id: T) -> Option<Indices<'_>> {
|
||||
self.args.get(&id.fnv_hash()).map(|arg| Indices {
|
||||
iter: arg.indices.iter().cloned(),
|
||||
})
|
||||
}
|
||||
|
@ -615,9 +615,9 @@ impl ArgMatches {
|
|||
/// [`Subcommand`]: ./struct..html
|
||||
/// [`App`]: ./struct.App.html
|
||||
/// [`ArgMatches`]: ./struct.ArgMatches.html
|
||||
pub fn subcommand_matches<T: Key>(&self, id: T) -> Option<&ArgMatches> {
|
||||
pub fn subcommand_matches<T: FnvHash>(&self, id: T) -> Option<&ArgMatches> {
|
||||
if let Some(ref s) = self.subcommand {
|
||||
if s.id == id.key() {
|
||||
if s.id == id.fnv_hash() {
|
||||
return Some(&s.matches);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use bstr::{BStr, BString};
|
|||
use crate::build::app::Propagation;
|
||||
use crate::build::AppSettings as AS;
|
||||
use crate::build::{App, Arg, ArgSettings};
|
||||
use crate::mkeymap::KeyType;
|
||||
use crate::mkeymap::MapKeyKind;
|
||||
use crate::output::Help;
|
||||
use crate::output::Usage;
|
||||
use crate::parse::errors::Error as ClapError;
|
||||
|
@ -20,7 +20,7 @@ use crate::parse::errors::Result as ClapResult;
|
|||
use crate::parse::features::suggestions;
|
||||
use crate::parse::Validator;
|
||||
use crate::parse::{ArgMatcher, SubCommand};
|
||||
use crate::util::{self, ChildGraph, Key, EMPTY_HASH};
|
||||
use crate::util::{self, ChildGraph, FnvHash, EMPTY_HASH};
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
use crate::INVALID_UTF8;
|
||||
|
||||
|
@ -99,7 +99,7 @@ where
|
|||
.iter()
|
||||
.map(|x| &x.key)
|
||||
.filter_map(|x| {
|
||||
if let KeyType::Position(n) = x {
|
||||
if let MapKeyKind::Position(n) = x {
|
||||
Some(n)
|
||||
} else {
|
||||
None
|
||||
|
@ -117,7 +117,7 @@ where
|
|||
.iter()
|
||||
.map(|x| &x.key)
|
||||
.filter(|x| {
|
||||
if let KeyType::Position(_) = x {
|
||||
if let MapKeyKind::Position(_) = x {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -235,7 +235,7 @@ where
|
|||
let mut found = false;
|
||||
for p in (1..=num_p)
|
||||
.rev()
|
||||
.filter_map(|n| self.app.args.get(&KeyType::Position(n as u64)))
|
||||
.filter_map(|n| self.app.args.get(&MapKeyKind::Position(n as u64)))
|
||||
{
|
||||
if found {
|
||||
assert!(
|
||||
|
@ -284,13 +284,13 @@ where
|
|||
debugln!("Parser::_build;");
|
||||
|
||||
//I wonder whether this part is even needed if we insert all Args using make_entries
|
||||
let mut key: Vec<(KeyType, usize)> = Vec::new();
|
||||
let mut key: Vec<(MapKeyKind, usize)> = Vec::new();
|
||||
let mut counter = 0;
|
||||
for (i, a) in self.app.args.args.iter_mut().enumerate() {
|
||||
if a.index == None && a.short == None && a.long == None {
|
||||
counter += 1;
|
||||
a.index = Some(counter);
|
||||
key.push((KeyType::Position(counter), i));
|
||||
key.push((MapKeyKind::Position(counter), i));
|
||||
}
|
||||
|
||||
// Add args with default requirements
|
||||
|
@ -492,7 +492,7 @@ where
|
|||
.iter()
|
||||
.map(|x| &x.key)
|
||||
.filter(|x| {
|
||||
if let KeyType::Position(_) = x {
|
||||
if let MapKeyKind::Position(_) = x {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -553,7 +553,7 @@ where
|
|||
.iter()
|
||||
.map(|x| &x.key)
|
||||
.filter(|x| {
|
||||
if let KeyType::Position(_) = x {
|
||||
if let MapKeyKind::Position(_) = x {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -625,7 +625,7 @@ where
|
|||
}
|
||||
sc_m.add_val_to(EMPTY_HASH, &a);
|
||||
}
|
||||
let id = sc_name.key();
|
||||
let id = sc_name.fnv_hash();
|
||||
matcher.subcommand(SubCommand {
|
||||
name: sc_name,
|
||||
id,
|
||||
|
@ -903,7 +903,7 @@ where
|
|||
p.get_matches_with(&mut sc_matcher, it)?;
|
||||
}
|
||||
let name = sc.name.clone();
|
||||
let sc_id = name.key();
|
||||
let sc_id = name.fnv_hash();
|
||||
matcher.subcommand(SubCommand {
|
||||
id: sc_id, // @TODO @maybe: should be sc.id?
|
||||
name,
|
||||
|
@ -1004,7 +1004,7 @@ where
|
|||
sdebugln!("No");
|
||||
full_arg.trim_left_matches(b'-')
|
||||
};
|
||||
if let Some(opt) = self.app.args.get(&KeyType::Long(arg.into())) {
|
||||
if let Some(opt) = self.app.args.get(&MapKeyKind::Long(arg.into())) {
|
||||
debugln!(
|
||||
"Parser::parse_long_arg: Found valid opt or flag '{}'",
|
||||
opt.to_string()
|
||||
|
@ -1069,7 +1069,7 @@ where
|
|||
// concatenated value: -oval
|
||||
// Option: -o
|
||||
// Value: val
|
||||
if let Some(opt) = self.app.args.get(&KeyType::Short(c)) {
|
||||
if let Some(opt) = self.app.args.get(&MapKeyKind::Short(c)) {
|
||||
debugln!(
|
||||
"Parser::parse_short_arg:iter:{}: Found valid opt or flag",
|
||||
c
|
||||
|
@ -1448,7 +1448,7 @@ where
|
|||
.iter()
|
||||
.map(|x| &x.key)
|
||||
.filter_map(|x| match x {
|
||||
KeyType::Long(l) => Some(l.to_string_lossy().into_owned()),
|
||||
MapKeyKind::Long(l) => Some(l.to_string_lossy().into_owned()),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -1462,7 +1462,7 @@ where
|
|||
|
||||
// Add the arg to the matches to build a proper usage string
|
||||
if let Some(ref name) = suffix.1 {
|
||||
if let Some(opt) = self.app.args.get(&KeyType::Long(BString::from(name))) {
|
||||
if let Some(opt) = self.app.args.get(&MapKeyKind::Long(BString::from(name))) {
|
||||
for g in groups_for_arg!(self.app, opt.id) {
|
||||
matcher.inc_occurrence_of(g);
|
||||
}
|
||||
|
|
|
@ -6,15 +6,15 @@ pub static VERSION_HASH: u64 = 0x30FF_0B7C_4D07_9478;
|
|||
pub static EMPTY_HASH: u64 = 0x1C9D_3ADB_639F_298E;
|
||||
const MAGIC_INIT: u64 = 0x811C_9DC5;
|
||||
|
||||
pub trait Key: Hash {
|
||||
fn key(&self) -> u64;
|
||||
pub trait FnvHash: Hash {
|
||||
fn fnv_hash(&self) -> u64;
|
||||
}
|
||||
|
||||
impl<T> Key for T
|
||||
impl<T> FnvHash for T
|
||||
where
|
||||
T: Hash,
|
||||
{
|
||||
fn key(&self) -> u64 {
|
||||
fn fnv_hash(&self) -> u64 {
|
||||
let mut hasher = FnvHasher::new();
|
||||
self.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
|
|
|
@ -4,7 +4,7 @@ mod map;
|
|||
mod osstringext;
|
||||
mod strext;
|
||||
|
||||
pub use self::fnv::{Key, EMPTY_HASH, HELP_HASH, VERSION_HASH};
|
||||
pub use self::fnv::{FnvHash, EMPTY_HASH, HELP_HASH, VERSION_HASH};
|
||||
pub use self::graph::ChildGraph;
|
||||
pub use self::map::{Values, VecMap};
|
||||
pub use self::osstringext::OsStrExt2;
|
||||
|
|
Loading…
Reference in a new issue