This commit is contained in:
Alena Yuryeva 2018-07-29 23:20:17 +05:00
parent c7131e3ed4
commit cc9518b9d4
13 changed files with 138 additions and 173 deletions

View file

@ -106,7 +106,7 @@ where
#[doc(hidden)]
pub g_settings: AppFlags,
#[doc(hidden)]
pub args: MKeyMap<'a, 'b>,
pub args: MKeyMap<Arg<'a, 'b>>,
#[doc(hidden)]
pub subcommands: Vec<App<'a, 'b>>,
#[doc(hidden)]
@ -988,18 +988,17 @@ impl<'a, 'b> App<'a, 'b> {
where
F: FnOnce(Arg<'a, 'b>) -> Arg<'a, 'b>,
{
let i = self
.args
.values()
.enumerate()
.filter_map(|(i, a)| if a.name == arg { Some(i) } else { None })
.next();
let a = if let Some(idx) = i {
let mut a = self.args.swap_remove(idx);
f(a)
// let i = self
// .args
// .values()
// .enumerate()
// .filter_map(|(i, a)| if a.name == arg { Some(i) } else { None })
// .next();
let a = if let Some(x) = self.args.remove_by_name(arg) {
f(x)
} else {
let mut a = Arg::with_name(arg);
f(a)
let mut x = Arg::with_name(arg);
f(x)
};
self.args.push(a);
self
@ -1747,7 +1746,7 @@ impl<'a, 'b> App<'a, 'b> {
}
}
pub(crate) fn contains_long(&self, l: &str) -> bool {
longs!(self).any(|&al| al == OsString::from(l).as_os_str())
longs!(self).any(|al| al == &OsString::from(l))
}
pub(crate) fn contains_short(&self, s: char) -> bool { shorts!(self).any(|&arg_s| arg_s == s) }
@ -1775,11 +1774,11 @@ impl<'a, 'b> App<'a, 'b> {
pub fn has_positionals(&self) -> bool { positionals!(self).count() > 0 }
pub fn has_visible_opts(&self) -> bool {
opts!(self).any(|(k, o)| !o.is_set(ArgSettings::Hidden))
opts!(self).any(|o| !o.is_set(ArgSettings::Hidden))
}
pub fn has_visible_flags(&self) -> bool {
flags!(self).any(|(k, o)| !o.is_set(ArgSettings::Hidden))
flags!(self).any(|o| !o.is_set(ArgSettings::Hidden))
}
pub fn has_visible_positionals(&self) -> bool {

View file

@ -132,7 +132,7 @@ complete -F _{name} -o bashdefault -o default {name}
p = &find_subcmd!(p, sc).unwrap();
}
let mut opts = String::new();
for (_, o) in opts!(p) {
for o in opts!(p) {
if let Some(l) = o.long {
opts = format!(
"{}
@ -182,7 +182,7 @@ complete -F _{name} -o bashdefault -o default {name}
shorts = shorts!(p).fold(String::new(), |acc, s| format!("{} -{}", acc, s)),
// Handles aliases too
// error-handling?
longs = longs!(p).fold(String::new(), |acc, l| format!("{} --{}", acc, l.to_str().unwrap()),
longs = longs!(p).fold(String::new(), |acc, l| format!("{} --{}", acc, l.to_str().unwrap())),
pos = positionals!(p).fold(String::new(), |acc, p| format!("{} {}", acc, p)),
// Handles aliases too
subcmds = sc_names!(p).fold(String::new(), |acc, s| format!("{} {}", acc, s))

View file

@ -80,7 +80,7 @@ where
let mut completions = String::new();
let preamble = String::from("\n cand ");
for (_, option) in opts!(p) {
for option in opts!(p) {
if let Some(data) = option.short {
let tooltip = get_tooltip(option.help, data);
completions.push_str(&preamble);
@ -93,7 +93,7 @@ where
}
}
for (_, flag) in flags!(p) {
for flag in flags!(p) {
if let Some(data) = flag.short {
let tooltip = get_tooltip(flag.help, data);
completions.push_str(&preamble);

View file

@ -44,7 +44,7 @@ fn gen_fish_inner(root_command: &str, comp_gen: &FishGen, subcommand: &str, buff
basic_template.push_str(format!("\"__fish_seen_subcommand_from {}\"", subcommand).as_str());
}
for (_, option) in opts!(comp_gen.0) {
for option in opts!(comp_gen.0) {
let mut template = basic_template.clone();
if let Some(data) = option.short {
template.push_str(format!(" -s {}", data).as_str());
@ -62,7 +62,7 @@ fn gen_fish_inner(root_command: &str, comp_gen: &FishGen, subcommand: &str, buff
buffer.push_str("\n");
}
for (_, flag) in flags!(comp_gen.0) {
for flag in flags!(comp_gen.0) {
let mut template = basic_template.clone();
if let Some(data) = flag.short {
template.push_str(format!(" -s {}", data).as_str());

View file

@ -79,7 +79,7 @@ fn generate_inner<'a, 'b, 'p>(
let mut completions = String::new();
let preamble = String::from("\n [CompletionResult]::new(");
for (_, option) in opts!(p) {
for option in opts!(p) {
if let Some(data) = option.short {
let tooltip = get_tooltip(option.help, data);
completions.push_str(&preamble);
@ -102,7 +102,7 @@ fn generate_inner<'a, 'b, 'p>(
}
}
for (_, flag) in flags!(p) {
for flag in flags!(p) {
if let Some(data) = flag.short {
let tooltip = get_tooltip(flag.help, data);
completions.push_str(&preamble);

View file

@ -334,7 +334,7 @@ fn escape_value(string: &str) -> String {
fn write_opts_of(p: &App) -> String {
debugln!("write_opts_of;");
let mut ret = vec![];
for (_, o) in opts!(p) {
for o in opts!(p) {
debugln!("write_opts_of:iter: o={}", o.name);
let help = o.help.map_or(String::new(), escape_help);
let mut conflicts = get_zsh_arg_conflicts!(p, o, INTERNAL_ERROR_MSG);
@ -399,7 +399,7 @@ fn write_opts_of(p: &App) -> String {
fn write_flags_of(p: &App) -> String {
debugln!("write_flags_of;");
let mut ret = vec![];
for (_, f) in flags!(p) {
for f in flags!(p) {
debugln!("write_flags_of:iter: f={}", f.name);
let help = f.help.map_or(String::new(), escape_help);
let mut conflicts = get_zsh_arg_conflicts!(p, f, INTERNAL_ERROR_MSG);

View file

@ -586,8 +586,6 @@ mod build;
mod mkeymap;
mod completions;
mod build;
mod completions;
mod output;
mod parse;

View file

@ -910,6 +910,7 @@ macro_rules! flags {
Position(_) => false,
})
.filter(|(k, a)| !a.help_heading.is_some())
.map(|(k, v)| v)
}};
($app:expr) => {
flags!($app, iter)
@ -935,6 +936,7 @@ macro_rules! opts {
Position(_) => false,
})
.filter(|(k, a)| !a.help_heading.is_some())
.map(|(k, v)| v)
}};
($app:expr) => {
opts!($app, iter)

View file

@ -4,40 +4,40 @@ use build::Arg;
use std::collections::hash_map;
use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::ffi::OsString;
use std::hash::{Hash, Hasher};
use std::slice;
// ! rustdoc
#[derive(Default, PartialEq, Debug, Clone)]
pub struct MKeyMap<'a, 'b>
where
'a: 'b,
pub struct MKeyMap<T>
{
keys: HashMap<KeyType<'a>, usize>,
value_index: Vec<Arg<'a, 'b>>,
keys: HashMap<KeyType, usize>,
value_index: Vec<T>,
values: HashMap<u64, HashSet<usize>>,
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum KeyType<'a> {
pub enum KeyType {
Short(char),
Long(&'a OsStr),
Long(OsString),
Position(usize),
}
impl<'a, 'b> MKeyMap<'a, 'b> {
impl <T> MKeyMap<T>
where T: Sized + Hash + PartialEq + Default + Eq
{
pub fn new() -> Self { MKeyMap::default() }
//TODO ::from(x), ::with_capacity(n) etc
//? set theory ops?
pub fn insert(&mut self, key: KeyType<'a>, value: Arg<'a, 'b>) -> usize {
pub fn insert(&mut self, key: KeyType, value: T) -> usize {
let index = self.push(value);
self.keys.insert(key, index);
index
}
pub fn push(&mut self, value: Arg<'a, 'b>) -> usize {
pub fn push(&mut self, value: T) -> usize {
let index;
let mut hasher = DefaultHasher::new();
@ -70,7 +70,7 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
}
//TODO ::push_many([x, y])
pub fn insert_key(&mut self, key: KeyType<'a>, index: usize) {
pub fn insert_key(&mut self, key: KeyType, index: usize) {
if index >= self.values.len() {
panic!("Index out of bounds");
}
@ -79,26 +79,26 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
}
//TODO ::insert_keyset([Long, Key2])
pub fn insert_key_by_name(&mut self, key: KeyType<'a>, name: &str) {
let index = self
.value_index
.iter()
.position(|x| x.name == name)
.expect("No such name found");
// pub fn insert_key_by_name(&mut self, key: KeyType, name: &str) {
// let index = self
// .value_index
// .iter()
// .position(|x| x.name == name)
// .expect("No such name found");
self.keys.insert(key, index);
}
// self.keys.insert(key, index);
// }
// ! Arg mutation functionality
pub fn get(&self, key: KeyType<'a>) -> Option<&Arg<'a, 'b>> {
pub fn get(&self, key: KeyType) -> Option<&T> {
self.keys
.get(&key)
.and_then(|&idx| self.value_index.get(idx))
}
//TODO ::get_first([KeyA, KeyB])
pub fn get_mut(&mut self, key: KeyType<'a>) -> Option<&mut Arg<'a, 'b>> {
pub fn get_mut(&mut self, key: KeyType) -> Option<&mut T> {
if let Some(&idx) = self.keys.get(&key) {
self.value_index.get_mut(idx)
} else {
@ -108,7 +108,9 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
pub fn is_empty(&self) -> bool { self.keys.is_empty() && self.values.is_empty() }
pub fn remove(&mut self, key: KeyType) -> Option<Arg> { unimplemented!() }
pub fn remove_by_name(&mut self, name: &str) -> Option<T> { unimplemented!() }
pub fn remove(&mut self, key: KeyType) -> Option<T> { unimplemented!() }
//TODO ::remove_many([KeyA, KeyB])
//? probably shouldn't add a possibility for removal?
//? or remove by replacement by some dummy object, so the order is preserved
@ -116,25 +118,27 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
pub fn remove_key(&mut self, key: KeyType) { unimplemented!() }
//TODO ::remove_keys([KeyA, KeyB])
pub fn keys(&'a self) -> Keys<'a, usize> {
pub fn keys(&self) -> Keys<usize> {
Keys {
iter: self.keys.keys(),
}
}
pub fn values(&'a self) -> Values<'a, Arg<'a, 'b>> {
pub fn values(&self) -> Values<T>
{
Values {
iter: self.value_index.iter(),
}
}
pub fn values_mut(&'a mut self) -> ValuesMut<'a, Arg<'a, 'b>> {
pub fn values_mut(&mut self) -> ValuesMut<T>
{
ValuesMut {
iter: self.value_index.iter_mut(),
}
}
pub fn iter(&self) -> Iter {
pub fn iter(&self) -> Iter<T> {
Iter {
map: self,
keys: self.keys(),
@ -142,13 +146,12 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
}
}
//TODO remove generics
pub struct Keys<'a, V: 'a> {
iter: hash_map::Keys<'a, KeyType<'a>, V>,
iter: hash_map::Keys<'a, KeyType, V>,
}
impl<'a, V> Iterator for Keys<'a, V> {
type Item = &'a KeyType<'a>;
type Item = &'a KeyType;
fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
}
@ -173,21 +176,17 @@ impl<'a, V> Iterator for ValuesMut<'a, V> {
fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
}
pub struct Iter<'a, 'b, 'c>
where
'a: 'b,
'b: 'c,
pub struct Iter<'c, T>
where T: 'c
{
map: &'c MKeyMap<'a, 'b>,
map: &'c MKeyMap<T>,
keys: Keys<'c, usize>,
}
impl<'a, 'b, 'c> Iterator for Iter<'a, 'b, 'c>
where
'a: 'b,
'b: 'c,
impl<'c, T> Iterator for Iter<'c, T>
where T: 'c + Sized + Hash + PartialEq + Default + Eq
{
type Item = (&'c KeyType<'a>, &'c Arg<'a, 'b>);
type Item = (&'c KeyType, &'c T);
fn next(&mut self) -> Option<Self::Item> {
if let Some(key) = self.keys.next() {
@ -206,12 +205,12 @@ mod tests {
#[test]
fn get_some_value() {
let mut map: MKeyMap = MKeyMap::new();
let mut map: MKeyMap<Arg> = MKeyMap::new();
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
assert_eq!(
map.get(Long(&OsStr::new("One"))),
map.get(Long(OsString::from("One"))),
Some(&Arg::with_name("Value1"))
);
}
@ -219,12 +218,12 @@ mod tests {
#[test]
#[should_panic]
fn get_none_value() {
let mut map: MKeyMap = MKeyMap::new();
let mut map: MKeyMap<Arg> = MKeyMap::new();
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
map.get(Long(&OsStr::new("Two")));
map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
map.get(Long(OsString::from("Two")));
assert_eq!(map.get(Long(&OsStr::new("Two"))), None);
assert_eq!(map.get(Long(OsString::from("Two"))), None);
}
// #[test]
@ -237,30 +236,30 @@ mod tests {
#[test]
fn insert_duplicate_key() {
let mut map: MKeyMap = MKeyMap::new();
let mut map: MKeyMap<Arg> = MKeyMap::new();
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
assert_eq!(
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value2")),
map.insert(Long(OsString::from("One")), Arg::with_name("Value2")),
1
);
}
#[test]
fn insert_duplicate_value() {
let mut map: MKeyMap = MKeyMap::new();
let mut map: MKeyMap<Arg> = MKeyMap::new();
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
let orig_len = map.values.len();
map.insert(Long(&OsStr::new("Two")), Arg::with_name("Value1"));
map.insert(Long(OsString::from("Two")), Arg::with_name("Value1"));
assert_eq!(map.values.len(), orig_len);
assert_eq!(
map.get(Long(&OsStr::new("One"))),
map.get(Long(&OsStr::new("Two")))
map.get(Long(OsString::from("One"))),
map.get(Long(OsString::from("Two")))
);
}
@ -275,51 +274,51 @@ mod tests {
#[test]
fn insert_multiple_keys() {
let mut map: MKeyMap = MKeyMap::new();
let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
let mut map: MKeyMap<Arg> = MKeyMap::new();
let index = map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
map.insert_key(Long(&OsStr::new("Two")), index);
map.insert_key(Long(OsString::from("Two")), index);
assert_eq!(
map.get(Long(&OsStr::new("One"))),
map.get(Long(&OsStr::new("Two")))
map.get(Long(OsString::from("One"))),
map.get(Long(OsString::from("Two")))
);
assert_eq!(map.values.len(), 1);
}
#[test]
fn insert_by_name() {
let mut map: MKeyMap = MKeyMap::new();
let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
// #[test]
// fn insert_by_name() {
// let mut map: MKeyMap<Arg> = MKeyMap::new();
// let index = map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
map.insert_key_by_name(Long(&OsStr::new("Two")), "Value1");
// map.insert_key_by_name(Long(OsString::from("Two")), "Value1");
assert_eq!(
map.get(Long(&OsStr::new("One"))),
map.get(Long(&OsStr::new("Two")))
);
assert_eq!(map.values.len(), 1);
}
// assert_eq!(
// map.get(Long(OsString::from("One"))),
// map.get(Long(OsString::from("Two")))
// );
// assert_eq!(map.values.len(), 1);
// }
#[test]
fn get_mutable() {
let mut map: MKeyMap = MKeyMap::new();
let mut map: MKeyMap<Arg> = MKeyMap::new();
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
assert_eq!(
map.get_mut(Long(&OsStr::new("One"))),
map.get_mut(Long(OsString::from("One"))),
Some(&mut Arg::with_name("Value1"))
);
}
#[test]
fn remove_key() {
let mut map: MKeyMap = MKeyMap::new();
let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
let mut map: MKeyMap<Arg> = MKeyMap::new();
let index = map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
map.insert_key(Long(&OsStr::new("Two")), index);
map.remove_key(Long(&OsStr::new("One")));
map.insert_key(Long(OsString::from("Two")), index);
map.remove_key(Long(OsString::from("One")));
assert_eq!(map.keys.len(), 1);
assert_eq!(map.values.len(), 1);
@ -327,17 +326,17 @@ mod tests {
#[test]
fn iter_keys() {
let mut map: MKeyMap = MKeyMap::new();
let mut map: MKeyMap<Arg> = MKeyMap::new();
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
map.insert(Long(&OsStr::new("Two")), Arg::with_name("Value2"));
map.insert(Long(OsString::from("One")), Arg::with_name("Value1"));
map.insert(Long(OsString::from("Two")), Arg::with_name("Value2"));
map.insert(Position(1), Arg::with_name("Value1"));
let iter = map.keys().cloned();
let mut ground_truth = HashSet::new();
ground_truth.insert(Long(&OsStr::new("One")));
ground_truth.insert(Long(&OsStr::new("Two")));
ground_truth.insert(Long(OsString::from("One")));
ground_truth.insert(Long(OsString::from("Two")));
ground_truth.insert(Position(1));
assert_eq!(

View file

@ -1082,7 +1082,7 @@ impl<'w> Help<'w> {
self.write_all_args(parser)?;
}
b"unified" => {
let opts_flags = parser.app.args.iter().filter(|a| a.has_switch());
let opts_flags = parser.app.args.values().filter(|a| a.has_switch());
self.write_args(opts_flags)?;
}
b"flags" => {

View file

@ -423,7 +423,7 @@ impl<'a, 'b, 'c, 'z> Usage<'a, 'b, 'c, 'z> {
let pmap = if let Some(m) = matcher {
desc_reqs
.iter()
.filter(|a| self.0.positionals.values().any(|p| &p == a))
.filter(|a| self.0.app.args.values().any(|p| p.name == **a))
.filter(|&pos| !m.contains(pos))
.filter_map(|pos| find!(self.0.app, pos))
.filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
@ -433,7 +433,7 @@ impl<'a, 'b, 'c, 'z> Usage<'a, 'b, 'c, 'z> {
} else {
desc_reqs
.iter()
.filter(|a| self.0.positionals.values().any(|p| &p == a))
.filter(|a| self.0.app.args.values().any(|p| p.name == **a))
.filter_map(|pos| find!(self.0.app, pos))
.filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
.filter(|pos| !args_in_groups.contains(&pos.name))

View file

@ -1,3 +1,4 @@
#![feature(nll)]
// Third Party
#[cfg(feature = "suggestions")]
use strsim;
@ -60,16 +61,16 @@ where
return (suffix, Some(candidate));
}
None => for subcommand in subcommands {
let longs = longs!(subcommand);
let longs = longs!(subcommand).map(|x| x.to_string_lossy().into_owned()).collect::<Vec<_>>();
if let Some(candidate) = did_you_mean(arg, longs) {
if let Some(candidate) = did_you_mean(arg, longs.iter()) {
let suffix = format!(
"\n\tDid you mean to put '{}{}' after the subcommand '{}'?",
Format::Good("--"),
Format::Good(candidate),
Format::Good(subcommand.get_name())
);
return (suffix, Some(candidate));
return (suffix, Some(candidate.clone()));
}
},
}

View file

@ -39,8 +39,6 @@ use parse::{ArgMatcher, SubCommand};
use util::OsStrExt2;
use INVALID_UTF8;
use INTERNAL_ERROR_MSG;
use parse::features::suggestions;
use output::Usage;
#[derive(Debug, PartialEq, Copy, Clone)]
#[doc(hidden)]
@ -72,32 +70,6 @@ where
cur_idx: Cell<usize>,
}
// Standalone split borrow functions
fn count_arg<'a, 'b>(
a: &mut Arg<'a, 'b>,
positionals: &mut VecMap<&'a str>,
num_opts: &mut usize,
num_flags: &mut usize,
) {
// Count types
if a.index.is_some() || (a.short.is_none() && a.long.is_none()) {
let i = if a.index.is_none() {
(positionals.len() + 1)
} else {
a.index.unwrap() as usize
};
a.index = Some(i as u64);
a.settings.set(ArgSettings::TakesValue);
positionals.insert(i, a.name);
} else if a.is_set(ArgSettings::TakesValue) {
*num_opts += 1;
// a.unified_ord = *num_flags + *num_opts;
} else {
*num_flags += 1;
// a.unified_ord = *num_flags + *num_opts;
}
}
// Initializing Methods
impl<'a, 'b, 'c> Parser<'a, 'b, 'c>
where
@ -337,22 +309,21 @@ where
// Does all the initializing and prepares the parser
pub(crate) fn _build(&mut self) {
debugln!("Parser::_build;");
let mut key: Vec<(KeyType, usize)> = Vec::new();
for (i, a) in self.app.args.values().enumerate() {
for (i, a) in self.app.args.values_mut().enumerate() {
if let Some(index) = a.index {
self.app.args.insert_key(KeyType::Position(index as usize), i);
if let Some(ref index) = a.index {
key.push((KeyType::Position((*index) as usize), i));
} else {
if let Some(c) = a.short {
self.app.args.insert_key(KeyType::Short(c), i);
if let Some(ref c) = a.short {
key.push((KeyType::Short(*c), i));
}
if let Some(l) = a.long {
self.app.args.insert_key(KeyType::Long(&OsStr::new(l)), i);
if let Some(ref l) = a.long {
key.push((KeyType::Long(OsString::from(l)), i));
}
if let Some(v) = a.aliases {
for (item, _) in &v {
self.app
.args
.insert_key(KeyType::Long(&OsStr::new(item)), i);
if let Some(ref v) = a.aliases {
for (item, _) in v {
key.push((KeyType::Long(OsString::from(item)), i));
}
}
}
@ -377,13 +348,9 @@ where
}
self.required.push(a.name);
}
count_arg(
a,
&mut self.positionals,
&mut self.num_opts,
&mut self.num_flags,
);
}
for (k, i) in key.into_iter() {
self.app.args.insert_key(k, i);
}
debug_assert!(self._verify_positionals());
@ -398,11 +365,8 @@ where
.filter(|x| if let KeyType::Position(_) = x { true } else { false })
.count())
//? what is happening below?
}) && self.positionals.values().last().map_or(false, |p_name| {
!find!(self.app, p_name)
.expect(INTERNAL_ERROR_MSG)
.is_set(ArgSettings::Last)
}) {
}) && self.app.args.iter().any(|(_, v)| v.is_set(ArgSettings::Last))
{
self.app.settings.set(AS::LowIndexMultiplePositional);
}
@ -1092,7 +1056,7 @@ where
full_arg.trim_left_matches(b'-')
};
// opts?? Should probably now check once, then check whether it's opt or flag, or sth else
if let Some(opt) = self.app.args.get(KeyType::Long(arg)) {
if let Some(opt) = self.app.args.get(KeyType::Long(arg.into())) {
debugln!(
"Parser::parse_long_arg: Found valid opt '{}'",
opt.to_string()
@ -1511,7 +1475,7 @@ where
};
}
for (k, o) in opts!(self.app) {
for o in opts!(self.app) {
debug!("Parser::add_defaults:iter:{}:", o.name);
add_val!(self, o, matcher);
}
@ -1553,16 +1517,18 @@ where
{
fn did_you_mean_error(&self, arg: &str, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
// Didn't match a flag or option
let longs = longs!(self.app).map(|x| x.to_string_lossy().into_owned()).collect::<Vec<_>>();
let suffix =
suggestions::did_you_mean_flag_suffix(arg, longs!(self.app), &*self.app.subcommands);
suggestions::did_you_mean_flag_suffix(arg, longs.iter().map(|ref x| &x[..] ), &*self.app.subcommands);
// Add the arg to the matches to build a proper usage string
if let Some(name) = suffix.1 {
if let Some(opt) = self.app.args.get(KeyType::Long(&OsStr::new(name))) {
if let Some(opt) = self.app.args.get(KeyType::Long(OsString::from(name))) {
self.groups_for_arg(&*opt.name)
.and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
matcher.insert(&*opt.name);
} else if let Some(flg) = self.app.args.get(KeyType::Long(&OsStr::new(name))) {
} else if let Some(flg) = self.app.args.get(KeyType::Long(OsString::from(name))) {
self.groups_for_arg(&*flg.name)
.and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
matcher.insert(&*flg.name);