diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index 2ae55197..01eb0f16 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -106,7 +106,7 @@ where #[doc(hidden)] pub g_settings: AppFlags, #[doc(hidden)] - pub args: MKeyMap<'a, 'b>, + pub args: MKeyMap>, #[doc(hidden)] pub subcommands: Vec>, #[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 { diff --git a/src/completions/bash.rs b/src/completions/bash.rs index a2163159..4f57682c 100644 --- a/src/completions/bash.rs +++ b/src/completions/bash.rs @@ -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)) diff --git a/src/completions/elvish.rs b/src/completions/elvish.rs index 17d2bd65..acba459b 100644 --- a/src/completions/elvish.rs +++ b/src/completions/elvish.rs @@ -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); diff --git a/src/completions/fish.rs b/src/completions/fish.rs index 8f4a3a14..9103a9c5 100644 --- a/src/completions/fish.rs +++ b/src/completions/fish.rs @@ -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()); diff --git a/src/completions/powershell.rs b/src/completions/powershell.rs index 636d8d2b..a9da8371 100644 --- a/src/completions/powershell.rs +++ b/src/completions/powershell.rs @@ -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); diff --git a/src/completions/zsh.rs b/src/completions/zsh.rs index 48cff835..cb27d25c 100644 --- a/src/completions/zsh.rs +++ b/src/completions/zsh.rs @@ -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); diff --git a/src/lib.rs b/src/lib.rs index 7bf14f00..312afddd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -586,8 +586,6 @@ mod build; mod mkeymap; -mod completions; -mod build; mod completions; mod output; mod parse; diff --git a/src/macros.rs b/src/macros.rs index 17fa96ec..4dc3a089 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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) diff --git a/src/mkeymap.rs b/src/mkeymap.rs index 4ffa3064..e2b520f8 100644 --- a/src/mkeymap.rs +++ b/src/mkeymap.rs @@ -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 { - keys: HashMap, usize>, - value_index: Vec>, + keys: HashMap, + value_index: Vec, values: HashMap>, } #[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 MKeyMap +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 { unimplemented!() } + pub fn remove_by_name(&mut self, name: &str) -> Option { unimplemented!() } + + pub fn remove(&mut self, key: KeyType) -> Option { 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 { Keys { iter: self.keys.keys(), } } - pub fn values(&'a self) -> Values<'a, Arg<'a, 'b>> { + pub fn values(&self) -> Values + { 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 + { ValuesMut { iter: self.value_index.iter_mut(), } } - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { 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.iter.next() } } @@ -173,21 +176,17 @@ impl<'a, V> Iterator for ValuesMut<'a, V> { fn next(&mut self) -> Option { 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, 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 { 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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!( diff --git a/src/output/help.rs b/src/output/help.rs index d18157bc..4e252099 100644 --- a/src/output/help.rs +++ b/src/output/help.rs @@ -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" => { diff --git a/src/output/usage.rs b/src/output/usage.rs index e7480543..491cbf0f 100644 --- a/src/output/usage.rs +++ b/src/output/usage.rs @@ -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)) diff --git a/src/parse/features/suggestions.rs b/src/parse/features/suggestions.rs index 491a7567..e4b136f6 100644 --- a/src/parse/features/suggestions.rs +++ b/src/parse/features/suggestions.rs @@ -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::>(); - 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())); } }, } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 6a10a3e6..68cac4b9 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -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, } -// 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::>(); + 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);