Merge pull request #1051 from malbarbo/master

make vec_map optional
This commit is contained in:
Kevin K 2017-10-03 21:49:01 -04:00 committed by GitHub
commit 3224e2e1cd
14 changed files with 107 additions and 31 deletions

View file

@ -21,7 +21,6 @@ appveyor = { repository = "kbknapp/clap-rs" }
[dependencies] [dependencies]
bitflags = "0.9" bitflags = "0.9"
vec_map = "0.8"
unicode-width = "0.1.4" unicode-width = "0.1.4"
textwrap = "0.8.0" textwrap = "0.8.0"
strsim = { version = "0.6.0", optional = true } strsim = { version = "0.6.0", optional = true }
@ -30,6 +29,7 @@ term_size = { version = "0.3.0", optional = true }
yaml-rust = { version = "0.3.5", optional = true } yaml-rust = { version = "0.3.5", optional = true }
clippy = { version = "~0.0.131", optional = true } clippy = { version = "~0.0.131", optional = true }
atty = { version = "0.2.2", optional = true } atty = { version = "0.2.2", optional = true }
vec_map = { version = "0.8", optional = true }
[dev-dependencies] [dev-dependencies]
regex = "0.2" regex = "0.2"
@ -37,7 +37,7 @@ lazy_static = "0.2"
version-sync = "0.3" version-sync = "0.3"
[features] [features]
default = ["suggestions", "color", "wrap_help"] default = ["suggestions", "color", "wrap_help", "vec_map"]
suggestions = ["strsim"] suggestions = ["strsim"]
color = ["ansi_term", "atty"] color = ["ansi_term", "atty"]
wrap_help = ["term_size"] wrap_help = ["term_size"]

View file

@ -490,6 +490,7 @@ Then run `cargo build` or `cargo update && cargo build` for your project.
* **"suggestions"**: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`) * **"suggestions"**: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`)
* **"color"**: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term`) * **"color"**: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term`)
* **"wrap_help"**: Wraps the help at the actual terminal width when available, instead of 120 characters. (builds dependency `term_size`) * **"wrap_help"**: Wraps the help at the actual terminal width when available, instead of 120 characters. (builds dependency `term_size`)
* **"vec_map"**: Use [`VecMap`](https://crates.io/crates/vec_map) internally instead of a [`BTreeMap`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html). This feature provides a _slight_ performance improvement. (builds dependency `vec_map`)
To disable these, add this to your `Cargo.toml`: To disable these, add this to your `Cargo.toml`:

View file

@ -12,13 +12,13 @@ use args::{AnyArg, ArgSettings, DispOrder};
use errors::{Error, Result as ClapResult}; use errors::{Error, Result as ClapResult};
use fmt::{Format, Colorizer, ColorizerOption}; use fmt::{Format, Colorizer, ColorizerOption};
use app::usage; use app::usage;
use map::VecMap;
// Third Party // Third Party
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
#[cfg(feature = "wrap_help")] #[cfg(feature = "wrap_help")]
use term_size; use term_size;
use textwrap; use textwrap;
use vec_map::VecMap;
#[cfg(not(feature = "wrap_help"))] #[cfg(not(feature = "wrap_help"))]
mod term_size { mod term_size {

View file

@ -18,7 +18,6 @@ use std::rc::Rc;
use std::result::Result as StdResult; use std::result::Result as StdResult;
// Third Party // Third Party
use vec_map::{self, VecMap};
#[cfg(feature = "yaml")] #[cfg(feature = "yaml")]
use yaml_rust::Yaml; use yaml_rust::Yaml;
@ -29,6 +28,7 @@ use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings};
use errors::Result as ClapResult; use errors::Result as ClapResult;
pub use self::settings::AppSettings; pub use self::settings::AppSettings;
use completions::Shell; use completions::Shell;
use map::{self, VecMap};
/// Used to create a representation of a command line program and all possible command line /// Used to create a representation of a command line program and all possible command line
/// arguments. Application settings are set using the "builder pattern" with the /// arguments. Application settings are set using the "builder pattern" with the
@ -1793,7 +1793,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
fn help(&self) -> Option<&'e str> { self.p.meta.about } fn help(&self) -> Option<&'e str> { self.p.meta.about }
fn long_help(&self) -> Option<&'e str> { self.p.meta.long_about } fn long_help(&self) -> Option<&'e str> { self.p.meta.long_about }
fn default_val(&self) -> Option<&'e OsStr> { None } fn default_val(&self) -> Option<&'e OsStr> { None }
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
None None
} }
fn longest_filter(&self) -> bool { true } fn longest_filter(&self) -> bool { true }

View file

@ -9,9 +9,6 @@ use std::path::PathBuf;
use std::slice::Iter; use std::slice::Iter;
use std::iter::Peekable; use std::iter::Peekable;
// Third Party
use vec_map::{self, VecMap};
// Internal // Internal
use INTERNAL_ERROR_MSG; use INTERNAL_ERROR_MSG;
use INVALID_UTF8; use INVALID_UTF8;
@ -32,6 +29,7 @@ use suggestions;
use app::settings::AppSettings as AS; use app::settings::AppSettings as AS;
use app::validator::Validator; use app::validator::Validator;
use app::usage; use app::usage;
use map::{self, VecMap};
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
#[doc(hidden)] #[doc(hidden)]
@ -1795,7 +1793,7 @@ impl<'a, 'b> Parser<'a, 'b>
pub fn opts(&self) -> Iter<OptBuilder<'a, 'b>> { self.opts.iter() } pub fn opts(&self) -> Iter<OptBuilder<'a, 'b>> { self.opts.iter() }
pub fn positionals(&self) -> vec_map::Values<PosBuilder<'a, 'b>> { self.positionals.values() } pub fn positionals(&self) -> map::Values<PosBuilder<'a, 'b>> { self.positionals.values() }
pub fn subcommands(&self) -> Iter<App> { self.subcommands.iter() } pub fn subcommands(&self) -> Iter<App> { self.subcommands.iter() }

View file

@ -3,11 +3,9 @@ use std::rc::Rc;
use std::fmt as std_fmt; use std::fmt as std_fmt;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
// Third Party
use vec_map::{self, VecMap};
// Internal // Internal
use args::settings::ArgSettings; use args::settings::ArgSettings;
use map::{self, VecMap};
#[doc(hidden)] #[doc(hidden)]
pub trait AnyArg<'n, 'e>: std_fmt::Display { pub trait AnyArg<'n, 'e>: std_fmt::Display {
@ -34,7 +32,7 @@ pub trait AnyArg<'n, 'e>: std_fmt::Display {
fn help(&self) -> Option<&'e str>; fn help(&self) -> Option<&'e str>;
fn long_help(&self) -> Option<&'e str>; fn long_help(&self) -> Option<&'e str>;
fn default_val(&self) -> Option<&'e OsStr>; fn default_val(&self) -> Option<&'e OsStr>;
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>; fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>;
fn longest_filter(&self) -> bool; fn longest_filter(&self) -> bool;
fn val_terminator(&self) -> Option<&'e str>; fn val_terminator(&self) -> Option<&'e str>;
} }

View file

@ -10,7 +10,7 @@ use std::os::unix::ffi::OsStrExt;
#[cfg(feature = "yaml")] #[cfg(feature = "yaml")]
use yaml_rust::Yaml; use yaml_rust::Yaml;
use vec_map::VecMap; use map::VecMap;
use usage_parser::UsageParser; use usage_parser::UsageParser;
use args::settings::ArgSettings; use args::settings::ArgSettings;

View file

@ -6,12 +6,10 @@ use std::result::Result as StdResult;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use std::mem; use std::mem;
// Third Party
use vec_map::{self, VecMap};
// Internal // Internal
use Arg; use Arg;
use args::{ArgSettings, Base, Switched, AnyArg, DispOrder}; use args::{ArgSettings, Base, Switched, AnyArg, DispOrder};
use map::{self, VecMap};
#[derive(Default, Clone, Debug)] #[derive(Default, Clone, Debug)]
#[doc(hidden)] #[doc(hidden)]
@ -82,7 +80,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
fn long_help(&self) -> Option<&'e str> { self.b.long_help } fn long_help(&self) -> Option<&'e str> { self.b.long_help }
fn val_terminator(&self) -> Option<&'e str> { None } fn val_terminator(&self) -> Option<&'e str> { None }
fn default_val(&self) -> Option<&'e OsStr> { None } fn default_val(&self) -> Option<&'e OsStr> { None }
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
None None
} }
fn longest_filter(&self) -> bool { self.s.long.is_some() } fn longest_filter(&self) -> bool { self.s.long.is_some() }

View file

@ -5,11 +5,9 @@ use std::result::Result as StdResult;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use std::mem; use std::mem;
// Third Party
use vec_map::{self, VecMap};
// Internal // Internal
use args::{ArgSettings, AnyArg, Base, Switched, Valued, Arg, DispOrder}; use args::{ArgSettings, AnyArg, Base, Switched, Valued, Arg, DispOrder};
use map::{self, VecMap};
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
#[doc(hidden)] #[doc(hidden)]
@ -131,7 +129,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> {
fn help(&self) -> Option<&'e str> { self.b.help } fn help(&self) -> Option<&'e str> { self.b.help }
fn long_help(&self) -> Option<&'e str> { self.b.long_help } fn long_help(&self) -> Option<&'e str> { self.b.long_help }
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val } fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
self.v.default_vals_ifs.as_ref().map(|vm| vm.values()) self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
} }
fn longest_filter(&self) -> bool { true } fn longest_filter(&self) -> bool { true }
@ -165,7 +163,7 @@ impl<'n, 'e> PartialEq for OptBuilder<'n, 'e> {
mod test { mod test {
use args::settings::ArgSettings; use args::settings::ArgSettings;
use super::OptBuilder; use super::OptBuilder;
use vec_map::VecMap; use map::VecMap;
#[test] #[test]
fn optbuilder_display1() { fn optbuilder_display1() {

View file

@ -6,13 +6,11 @@ use std::result::Result as StdResult;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use std::mem; use std::mem;
// Third Party
use vec_map::{self, VecMap};
// Internal // Internal
use Arg; use Arg;
use args::{ArgSettings, Base, Valued, AnyArg, DispOrder}; use args::{ArgSettings, Base, Valued, AnyArg, DispOrder};
use INTERNAL_ERROR_MSG; use INTERNAL_ERROR_MSG;
use map::{self, VecMap};
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
#[doc(hidden)] #[doc(hidden)]
@ -141,7 +139,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
fn takes_value(&self) -> bool { true } fn takes_value(&self) -> bool { true }
fn help(&self) -> Option<&'e str> { self.b.help } fn help(&self) -> Option<&'e str> { self.b.help }
fn long_help(&self) -> Option<&'e str> { self.b.long_help } fn long_help(&self) -> Option<&'e str> { self.b.long_help }
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
self.v.default_vals_ifs.as_ref().map(|vm| vm.values()) self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
} }
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val } fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
@ -161,7 +159,7 @@ impl<'n, 'e> PartialEq for PosBuilder<'n, 'e> {
mod test { mod test {
use args::settings::ArgSettings; use args::settings::ArgSettings;
use super::PosBuilder; use super::PosBuilder;
use vec_map::VecMap; use map::VecMap;
#[test] #[test]
fn display_mult() { fn display_mult() {

View file

@ -1,7 +1,7 @@
use std::rc::Rc; use std::rc::Rc;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use vec_map::VecMap; use map::VecMap;
use Arg; use Arg;

View file

@ -539,6 +539,7 @@ extern crate yaml_rust;
extern crate unicode_width; extern crate unicode_width;
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
#[cfg(feature = "vec_map")]
extern crate vec_map; extern crate vec_map;
#[cfg(feature = "wrap_help")] #[cfg(feature = "wrap_help")]
extern crate term_size; extern crate term_size;
@ -565,6 +566,7 @@ mod errors;
mod osstringext; mod osstringext;
mod strext; mod strext;
mod completions; mod completions;
mod map;
const INTERNAL_ERROR_MSG: &'static str = "Fatal internal error. Please consider filing a bug \ const INTERNAL_ERROR_MSG: &'static str = "Fatal internal error. Please consider filing a bug \
report at https://github.com/kbknapp/clap-rs/issues"; report at https://github.com/kbknapp/clap-rs/issues";

84
src/map.rs Normal file
View file

@ -0,0 +1,84 @@
#[cfg(feature = "vec_map")]
pub use vec_map::{VecMap, Values};
#[cfg(not(feature = "vec_map"))]
pub use self::vec_map::{VecMap, Values};
#[cfg(not(feature = "vec_map"))]
mod vec_map {
use std::collections::BTreeMap;
use std::collections::btree_map;
use std::fmt::{self, Debug, Formatter};
#[derive(Clone, Default, Debug)]
pub struct VecMap<V> {
inner: BTreeMap<usize, V>,
}
impl<V> VecMap<V> {
pub fn new() -> Self {
VecMap { inner: Default::default() }
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn insert(&mut self, key: usize, value: V) -> Option<V> {
self.inner.insert(key, value)
}
pub fn values(&self) -> Values<V> {
self.inner.values()
}
pub fn iter(&self) -> Iter<V> {
Iter { inner: self.inner.iter() }
}
pub fn contains_key(&self, key: usize) -> bool {
self.inner.contains_key(&key)
}
pub fn entry(&mut self, key: usize) -> Entry<V> {
self.inner.entry(key)
}
pub fn get(&self, key: usize) -> Option<&V> {
self.inner.get(&key)
}
}
pub type Values<'a, V> = btree_map::Values<'a, usize, V>;
pub type Entry<'a, V> = btree_map::Entry<'a, usize, V>;
#[derive(Clone)]
pub struct Iter<'a, V: 'a> {
inner: btree_map::Iter<'a, usize, V>,
}
impl<'a, V: 'a + Debug> Debug for Iter<'a, V> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_list().entries(self.inner.clone()).finish()
}
}
impl<'a, V: 'a> Iterator for Iter<'a, V> {
type Item = (usize, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, v)| (*k, v))
}
}
impl<'a, V: 'a> DoubleEndedIterator for Iter<'a, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(k, v)| (*k, v))
}
}
}

View file

@ -1,10 +1,9 @@
// Third Party
use vec_map::VecMap;
// Internal // Internal
use INTERNAL_ERROR_MSG; use INTERNAL_ERROR_MSG;
use args::Arg; use args::Arg;
use args::settings::ArgSettings; use args::settings::ArgSettings;
use map::VecMap;
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
enum UsageToken { enum UsageToken {