aboutsummaryrefslogtreecommitdiff
path: root/clap/src/args/arg_builder
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-01-07 11:18:04 +0000
committerDaniel Mueller <deso@posteo.net>2020-01-08 09:20:25 -0800
commit5e20a29b4fdc8a2d442d1093681b396dcb4b816b (patch)
tree55ab083fa8999d2ccbb5e921c1ffe52560dca152 /clap/src/args/arg_builder
parent203e691f46d591a2cc8acdfd850fa9f5b0fb8a98 (diff)
downloadnitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.gz
nitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.bz2
Add structopt dependency in version 0.3.7
This patch series replaces argparse with structopt in the argument handling code. As a first step, we need structopt as a dependency. Import subrepo structopt/:structopt at efbdda4753592e27bc430fb01f7b9650b2f3174d Import subrepo bitflags/:bitflags at 30668016aca6bd3b02c766e8347e0b4080d4c296 Import subrepo clap/:clap at 784524f7eb193e35f81082cc69454c8c21b948f7 Import subrepo heck/:heck at 093d56fbf001e1506e56dbfa38631d99b1066df1 Import subrepo proc-macro-error/:proc-macro-error at 6c4cfe79a622c5de8ae68557993542be46eacae2 Import subrepo proc-macro2/:proc-macro2 at d5d48eddca4566e5438e8a2cbed4a74e049544de Import subrepo quote/:quote at 727436c6c137b20f0f34dde5d8fda2679b9747ad Import subrepo rustversion/:rustversion at 0c5663313516263059ce9059ef81fc7a1cf655ca Import subrepo syn-mid/:syn-mid at 5d3d85414a9e6674e1857ec22a87b96e04a6851a Import subrepo syn/:syn at e87c27e87f6f4ef8919d0372bdb056d53ef0d8f3 Import subrepo textwrap/:textwrap at abcd618beae3f74841032aa5b53c1086b0a57ca2 Import subrepo unicode-segmentation/:unicode-segmentation at 637c9874c4fe0c205ff27787faf150a40295c6c3 Import subrepo unicode-width/:unicode-width at 3033826f8bf05e82724140a981d5941e48fce393 Import subrepo unicode-xid/:unicode-xid at 4baae9fffb156ba229665b972a9cd5991787ceb7
Diffstat (limited to 'clap/src/args/arg_builder')
-rw-r--r--clap/src/args/arg_builder/base.rs38
-rw-r--r--clap/src/args/arg_builder/flag.rs159
-rw-r--r--clap/src/args/arg_builder/mod.rs13
-rw-r--r--clap/src/args/arg_builder/option.rs244
-rw-r--r--clap/src/args/arg_builder/positional.rs229
-rw-r--r--clap/src/args/arg_builder/switched.rs38
-rw-r--r--clap/src/args/arg_builder/valued.rs67
7 files changed, 788 insertions, 0 deletions
diff --git a/clap/src/args/arg_builder/base.rs b/clap/src/args/arg_builder/base.rs
new file mode 100644
index 0000000..fef9d8a
--- /dev/null
+++ b/clap/src/args/arg_builder/base.rs
@@ -0,0 +1,38 @@
+use args::{Arg, ArgFlags, ArgSettings};
+
+#[derive(Debug, Clone, Default)]
+pub struct Base<'a, 'b>
+where
+ 'a: 'b,
+{
+ pub name: &'a str,
+ pub help: Option<&'b str>,
+ pub long_help: Option<&'b str>,
+ pub blacklist: Option<Vec<&'a str>>,
+ pub settings: ArgFlags,
+ pub r_unless: Option<Vec<&'a str>>,
+ pub overrides: Option<Vec<&'a str>>,
+ pub groups: Option<Vec<&'a str>>,
+ pub requires: Option<Vec<(Option<&'b str>, &'a str)>>,
+}
+
+impl<'n, 'e> Base<'n, 'e> {
+ pub fn new(name: &'n str) -> Self {
+ Base {
+ name: name,
+ ..Default::default()
+ }
+ }
+
+ pub fn set(&mut self, s: ArgSettings) { self.settings.set(s); }
+ pub fn unset(&mut self, s: ArgSettings) { self.settings.unset(s); }
+ pub fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
+}
+
+impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for Base<'n, 'e> {
+ fn from(a: &'z Arg<'n, 'e>) -> Self { a.b.clone() }
+}
+
+impl<'n, 'e> PartialEq for Base<'n, 'e> {
+ fn eq(&self, other: &Base<'n, 'e>) -> bool { self.name == other.name }
+}
diff --git a/clap/src/args/arg_builder/flag.rs b/clap/src/args/arg_builder/flag.rs
new file mode 100644
index 0000000..641e777
--- /dev/null
+++ b/clap/src/args/arg_builder/flag.rs
@@ -0,0 +1,159 @@
+// Std
+use std::convert::From;
+use std::fmt::{Display, Formatter, Result};
+use std::rc::Rc;
+use std::result::Result as StdResult;
+use std::ffi::{OsStr, OsString};
+use std::mem;
+
+// Internal
+use Arg;
+use args::{AnyArg, ArgSettings, Base, DispOrder, Switched};
+use map::{self, VecMap};
+
+#[derive(Default, Clone, Debug)]
+#[doc(hidden)]
+pub struct FlagBuilder<'n, 'e>
+where
+ 'n: 'e,
+{
+ pub b: Base<'n, 'e>,
+ pub s: Switched<'e>,
+}
+
+impl<'n, 'e> FlagBuilder<'n, 'e> {
+ pub fn new(name: &'n str) -> Self {
+ FlagBuilder {
+ b: Base::new(name),
+ ..Default::default()
+ }
+ }
+}
+
+impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
+ fn from(a: &'z Arg<'a, 'b>) -> Self {
+ FlagBuilder {
+ b: Base::from(a),
+ s: Switched::from(a),
+ }
+ }
+}
+
+impl<'a, 'b> From<Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
+ fn from(mut a: Arg<'a, 'b>) -> Self {
+ FlagBuilder {
+ b: mem::replace(&mut a.b, Base::default()),
+ s: mem::replace(&mut a.s, Switched::default()),
+ }
+ }
+}
+
+impl<'n, 'e> Display for FlagBuilder<'n, 'e> {
+ fn fmt(&self, f: &mut Formatter) -> Result {
+ if let Some(l) = self.s.long {
+ write!(f, "--{}", l)?;
+ } else {
+ write!(f, "-{}", self.s.short.unwrap())?;
+ }
+
+ Ok(())
+ }
+}
+
+impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
+ fn name(&self) -> &'n str { self.b.name }
+ fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
+ fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
+ self.b.requires.as_ref().map(|o| &o[..])
+ }
+ fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
+ fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
+ fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
+ fn has_switch(&self) -> bool { true }
+ fn takes_value(&self) -> bool { false }
+ fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
+ fn max_vals(&self) -> Option<u64> { None }
+ fn val_names(&self) -> Option<&VecMap<&'e str>> { None }
+ fn num_vals(&self) -> Option<u64> { None }
+ fn possible_vals(&self) -> Option<&[&'e str]> { None }
+ fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
+ fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None }
+ fn min_vals(&self) -> Option<u64> { None }
+ fn short(&self) -> Option<char> { self.s.short }
+ fn long(&self) -> Option<&'e str> { self.s.long }
+ fn val_delim(&self) -> Option<char> { None }
+ fn help(&self) -> Option<&'e str> { self.b.help }
+ fn long_help(&self) -> Option<&'e str> { self.b.long_help }
+ fn val_terminator(&self) -> Option<&'e str> { None }
+ fn default_val(&self) -> Option<&'e OsStr> { None }
+ fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
+ None
+ }
+ fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> { None }
+ fn longest_filter(&self) -> bool { self.s.long.is_some() }
+ fn aliases(&self) -> Option<Vec<&'e str>> {
+ if let Some(ref aliases) = self.s.aliases {
+ let vis_aliases: Vec<_> = aliases
+ .iter()
+ .filter_map(|&(n, v)| if v { Some(n) } else { None })
+ .collect();
+ if vis_aliases.is_empty() {
+ None
+ } else {
+ Some(vis_aliases)
+ }
+ } else {
+ None
+ }
+ }
+}
+
+impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> {
+ fn disp_ord(&self) -> usize { self.s.disp_ord }
+}
+
+impl<'n, 'e> PartialEq for FlagBuilder<'n, 'e> {
+ fn eq(&self, other: &FlagBuilder<'n, 'e>) -> bool { self.b == other.b }
+}
+
+#[cfg(test)]
+mod test {
+ use args::settings::ArgSettings;
+ use super::FlagBuilder;
+
+ #[test]
+ fn flagbuilder_display() {
+ let mut f = FlagBuilder::new("flg");
+ f.b.settings.set(ArgSettings::Multiple);
+ f.s.long = Some("flag");
+
+ assert_eq!(&*format!("{}", f), "--flag");
+
+ let mut f2 = FlagBuilder::new("flg");
+ f2.s.short = Some('f');
+
+ assert_eq!(&*format!("{}", f2), "-f");
+ }
+
+ #[test]
+ fn flagbuilder_display_single_alias() {
+ let mut f = FlagBuilder::new("flg");
+ f.s.long = Some("flag");
+ f.s.aliases = Some(vec![("als", true)]);
+
+ assert_eq!(&*format!("{}", f), "--flag");
+ }
+
+ #[test]
+ fn flagbuilder_display_multiple_aliases() {
+ let mut f = FlagBuilder::new("flg");
+ f.s.short = Some('f');
+ f.s.aliases = Some(vec![
+ ("alias_not_visible", false),
+ ("f2", true),
+ ("f3", true),
+ ("f4", true),
+ ]);
+ assert_eq!(&*format!("{}", f), "-f");
+ }
+}
diff --git a/clap/src/args/arg_builder/mod.rs b/clap/src/args/arg_builder/mod.rs
new file mode 100644
index 0000000..d1a7a66
--- /dev/null
+++ b/clap/src/args/arg_builder/mod.rs
@@ -0,0 +1,13 @@
+pub use self::flag::FlagBuilder;
+pub use self::option::OptBuilder;
+pub use self::positional::PosBuilder;
+pub use self::base::Base;
+pub use self::switched::Switched;
+pub use self::valued::Valued;
+
+mod flag;
+mod positional;
+mod option;
+mod base;
+mod valued;
+mod switched;
diff --git a/clap/src/args/arg_builder/option.rs b/clap/src/args/arg_builder/option.rs
new file mode 100644
index 0000000..4bb147a
--- /dev/null
+++ b/clap/src/args/arg_builder/option.rs
@@ -0,0 +1,244 @@
+// Std
+use std::fmt::{Display, Formatter, Result};
+use std::rc::Rc;
+use std::result::Result as StdResult;
+use std::ffi::{OsStr, OsString};
+use std::mem;
+
+// Internal
+use args::{AnyArg, Arg, ArgSettings, Base, DispOrder, Switched, Valued};
+use map::{self, VecMap};
+use INTERNAL_ERROR_MSG;
+
+#[allow(missing_debug_implementations)]
+#[doc(hidden)]
+#[derive(Default, Clone)]
+pub struct OptBuilder<'n, 'e>
+where
+ 'n: 'e,
+{
+ pub b: Base<'n, 'e>,
+ pub s: Switched<'e>,
+ pub v: Valued<'n, 'e>,
+}
+
+impl<'n, 'e> OptBuilder<'n, 'e> {
+ pub fn new(name: &'n str) -> Self {
+ OptBuilder {
+ b: Base::new(name),
+ ..Default::default()
+ }
+ }
+}
+
+impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for OptBuilder<'n, 'e> {
+ fn from(a: &'z Arg<'n, 'e>) -> Self {
+ OptBuilder {
+ b: Base::from(a),
+ s: Switched::from(a),
+ v: Valued::from(a),
+ }
+ }
+}
+
+impl<'n, 'e> From<Arg<'n, 'e>> for OptBuilder<'n, 'e> {
+ fn from(mut a: Arg<'n, 'e>) -> Self {
+ a.v.fill_in();
+ OptBuilder {
+ b: mem::replace(&mut a.b, Base::default()),
+ s: mem::replace(&mut a.s, Switched::default()),
+ v: mem::replace(&mut a.v, Valued::default()),
+ }
+ }
+}
+
+impl<'n, 'e> Display for OptBuilder<'n, 'e> {
+ fn fmt(&self, f: &mut Formatter) -> Result {
+ debugln!("OptBuilder::fmt:{}", self.b.name);
+ let sep = if self.b.is_set(ArgSettings::RequireEquals) {
+ "="
+ } else {
+ " "
+ };
+ // Write the name such --long or -l
+ if let Some(l) = self.s.long {
+ write!(f, "--{}{}", l, sep)?;
+ } else {
+ write!(f, "-{}{}", self.s.short.unwrap(), sep)?;
+ }
+ let delim = if self.is_set(ArgSettings::RequireDelimiter) {
+ self.v.val_delim.expect(INTERNAL_ERROR_MSG)
+ } else {
+ ' '
+ };
+
+ // Write the values such as <name1> <name2>
+ if let Some(ref vec) = self.v.val_names {
+ let mut it = vec.iter().peekable();
+ while let Some((_, val)) = it.next() {
+ write!(f, "<{}>", val)?;
+ if it.peek().is_some() {
+ write!(f, "{}", delim)?;
+ }
+ }
+ let num = vec.len();
+ if self.is_set(ArgSettings::Multiple) && num == 1 {
+ write!(f, "...")?;
+ }
+ } else if let Some(num) = self.v.num_vals {
+ let mut it = (0..num).peekable();
+ while let Some(_) = it.next() {
+ write!(f, "<{}>", self.b.name)?;
+ if it.peek().is_some() {
+ write!(f, "{}", delim)?;
+ }
+ }
+ if self.is_set(ArgSettings::Multiple) && num == 1 {
+ write!(f, "...")?;
+ }
+ } else {
+ write!(
+ f,
+ "<{}>{}",
+ self.b.name,
+ if self.is_set(ArgSettings::Multiple) {
+ "..."
+ } else {
+ ""
+ }
+ )?;
+ }
+
+ Ok(())
+ }
+}
+
+impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> {
+ fn name(&self) -> &'n str { self.b.name }
+ fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
+ fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
+ self.b.requires.as_ref().map(|o| &o[..])
+ }
+ fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
+ fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
+ fn val_names(&self) -> Option<&VecMap<&'e str>> { self.v.val_names.as_ref() }
+ fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
+ fn has_switch(&self) -> bool { true }
+ fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
+ fn max_vals(&self) -> Option<u64> { self.v.max_vals }
+ fn val_terminator(&self) -> Option<&'e str> { self.v.terminator }
+ fn num_vals(&self) -> Option<u64> { self.v.num_vals }
+ fn possible_vals(&self) -> Option<&[&'e str]> { self.v.possible_vals.as_ref().map(|o| &o[..]) }
+ fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
+ self.v.validator.as_ref()
+ }
+ fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
+ self.v.validator_os.as_ref()
+ }
+ fn min_vals(&self) -> Option<u64> { self.v.min_vals }
+ fn short(&self) -> Option<char> { self.s.short }
+ fn long(&self) -> Option<&'e str> { self.s.long }
+ fn val_delim(&self) -> Option<char> { self.v.val_delim }
+ fn takes_value(&self) -> bool { true }
+ fn help(&self) -> Option<&'e str> { self.b.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_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
+ self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
+ }
+ fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
+ self.v
+ .env
+ .as_ref()
+ .map(|&(key, ref value)| (key, value.as_ref()))
+ }
+ fn longest_filter(&self) -> bool { true }
+ fn aliases(&self) -> Option<Vec<&'e str>> {
+ if let Some(ref aliases) = self.s.aliases {
+ let vis_aliases: Vec<_> = aliases
+ .iter()
+ .filter_map(|&(n, v)| if v { Some(n) } else { None })
+ .collect();
+ if vis_aliases.is_empty() {
+ None
+ } else {
+ Some(vis_aliases)
+ }
+ } else {
+ None
+ }
+ }
+}
+
+impl<'n, 'e> DispOrder for OptBuilder<'n, 'e> {
+ fn disp_ord(&self) -> usize { self.s.disp_ord }
+}
+
+impl<'n, 'e> PartialEq for OptBuilder<'n, 'e> {
+ fn eq(&self, other: &OptBuilder<'n, 'e>) -> bool { self.b == other.b }
+}
+
+#[cfg(test)]
+mod test {
+ use args::settings::ArgSettings;
+ use super::OptBuilder;
+ use map::VecMap;
+
+ #[test]
+ fn optbuilder_display1() {
+ let mut o = OptBuilder::new("opt");
+ o.s.long = Some("option");
+ o.b.settings.set(ArgSettings::Multiple);
+
+ assert_eq!(&*format!("{}", o), "--option <opt>...");
+ }
+
+ #[test]
+ fn optbuilder_display2() {
+ let mut v_names = VecMap::new();
+ v_names.insert(0, "file");
+ v_names.insert(1, "name");
+
+ let mut o2 = OptBuilder::new("opt");
+ o2.s.short = Some('o');
+ o2.v.val_names = Some(v_names);
+
+ assert_eq!(&*format!("{}", o2), "-o <file> <name>");
+ }
+
+ #[test]
+ fn optbuilder_display3() {
+ let mut v_names = VecMap::new();
+ v_names.insert(0, "file");
+ v_names.insert(1, "name");
+
+ let mut o2 = OptBuilder::new("opt");
+ o2.s.short = Some('o');
+ o2.v.val_names = Some(v_names);
+ o2.b.settings.set(ArgSettings::Multiple);
+
+ assert_eq!(&*format!("{}", o2), "-o <file> <name>");
+ }
+
+ #[test]
+ fn optbuilder_display_single_alias() {
+ let mut o = OptBuilder::new("opt");
+ o.s.long = Some("option");
+ o.s.aliases = Some(vec![("als", true)]);
+
+ assert_eq!(&*format!("{}", o), "--option <opt>");
+ }
+
+ #[test]
+ fn optbuilder_display_multiple_aliases() {
+ let mut o = OptBuilder::new("opt");
+ o.s.long = Some("option");
+ o.s.aliases = Some(vec![
+ ("als_not_visible", false),
+ ("als2", true),
+ ("als3", true),
+ ("als4", true),
+ ]);
+ assert_eq!(&*format!("{}", o), "--option <opt>");
+ }
+}
diff --git a/clap/src/args/arg_builder/positional.rs b/clap/src/args/arg_builder/positional.rs
new file mode 100644
index 0000000..43fdca4
--- /dev/null
+++ b/clap/src/args/arg_builder/positional.rs
@@ -0,0 +1,229 @@
+// Std
+use std::borrow::Cow;
+use std::fmt::{Display, Formatter, Result};
+use std::rc::Rc;
+use std::result::Result as StdResult;
+use std::ffi::{OsStr, OsString};
+use std::mem;
+
+// Internal
+use Arg;
+use args::{AnyArg, ArgSettings, Base, DispOrder, Valued};
+use INTERNAL_ERROR_MSG;
+use map::{self, VecMap};
+
+#[allow(missing_debug_implementations)]
+#[doc(hidden)]
+#[derive(Clone, Default)]
+pub struct PosBuilder<'n, 'e>
+where
+ 'n: 'e,
+{
+ pub b: Base<'n, 'e>,
+ pub v: Valued<'n, 'e>,
+ pub index: u64,
+}
+
+impl<'n, 'e> PosBuilder<'n, 'e> {
+ pub fn new(name: &'n str, idx: u64) -> Self {
+ PosBuilder {
+ b: Base::new(name),
+ index: idx,
+ ..Default::default()
+ }
+ }
+
+ pub fn from_arg_ref(a: &Arg<'n, 'e>, idx: u64) -> Self {
+ let mut pb = PosBuilder {
+ b: Base::from(a),
+ v: Valued::from(a),
+ index: idx,
+ };
+ if a.v.max_vals.is_some() || a.v.min_vals.is_some()
+ || (a.v.num_vals.is_some() && a.v.num_vals.unwrap() > 1)
+ {
+ pb.b.settings.set(ArgSettings::Multiple);
+ }
+ pb
+ }
+
+ pub fn from_arg(mut a: Arg<'n, 'e>, idx: u64) -> Self {
+ if a.v.max_vals.is_some() || a.v.min_vals.is_some()
+ || (a.v.num_vals.is_some() && a.v.num_vals.unwrap() > 1)
+ {
+ a.b.settings.set(ArgSettings::Multiple);
+ }
+ PosBuilder {
+ b: mem::replace(&mut a.b, Base::default()),
+ v: mem::replace(&mut a.v, Valued::default()),
+ index: idx,
+ }
+ }
+
+ pub fn multiple_str(&self) -> &str {
+ let mult_vals = self.v
+ .val_names
+ .as_ref()
+ .map_or(true, |names| names.len() < 2);
+ if self.is_set(ArgSettings::Multiple) && mult_vals {
+ "..."
+ } else {
+ ""
+ }
+ }
+
+ pub fn name_no_brackets(&self) -> Cow<str> {
+ debugln!("PosBuilder::name_no_brackets;");
+ let mut delim = String::new();
+ delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
+ self.v.val_delim.expect(INTERNAL_ERROR_MSG)
+ } else {
+ ' '
+ });
+ if let Some(ref names) = self.v.val_names {
+ debugln!("PosBuilder:name_no_brackets: val_names={:#?}", names);
+ if names.len() > 1 {
+ Cow::Owned(
+ names
+ .values()
+ .map(|n| format!("<{}>", n))
+ .collect::<Vec<_>>()
+ .join(&*delim),
+ )
+ } else {
+ Cow::Borrowed(names.values().next().expect(INTERNAL_ERROR_MSG))
+ }
+ } else {
+ debugln!("PosBuilder:name_no_brackets: just name");
+ Cow::Borrowed(self.b.name)
+ }
+ }
+}
+
+impl<'n, 'e> Display for PosBuilder<'n, 'e> {
+ fn fmt(&self, f: &mut Formatter) -> Result {
+ let mut delim = String::new();
+ delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
+ self.v.val_delim.expect(INTERNAL_ERROR_MSG)
+ } else {
+ ' '
+ });
+ if let Some(ref names) = self.v.val_names {
+ write!(
+ f,
+ "{}",
+ names
+ .values()
+ .map(|n| format!("<{}>", n))
+ .collect::<Vec<_>>()
+ .join(&*delim)
+ )?;
+ } else {
+ write!(f, "<{}>", self.b.name)?;
+ }
+ if self.b.settings.is_set(ArgSettings::Multiple)
+ && (self.v.val_names.is_none() || self.v.val_names.as_ref().unwrap().len() == 1)
+ {
+ write!(f, "...")?;
+ }
+
+ Ok(())
+ }
+}
+
+impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
+ fn name(&self) -> &'n str { self.b.name }
+ fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
+ fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
+ self.b.requires.as_ref().map(|o| &o[..])
+ }
+ fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
+ fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
+ fn val_names(&self) -> Option<&VecMap<&'e str>> { self.v.val_names.as_ref() }
+ fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
+ fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
+ fn has_switch(&self) -> bool { false }
+ fn max_vals(&self) -> Option<u64> { self.v.max_vals }
+ fn val_terminator(&self) -> Option<&'e str> { self.v.terminator }
+ fn num_vals(&self) -> Option<u64> { self.v.num_vals }
+ fn possible_vals(&self) -> Option<&[&'e str]> { self.v.possible_vals.as_ref().map(|o| &o[..]) }
+ fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
+ self.v.validator.as_ref()
+ }
+ fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
+ self.v.validator_os.as_ref()
+ }
+ fn min_vals(&self) -> Option<u64> { self.v.min_vals }
+ fn short(&self) -> Option<char> { None }
+ fn long(&self) -> Option<&'e str> { None }
+ fn val_delim(&self) -> Option<char> { self.v.val_delim }
+ fn takes_value(&self) -> bool { true }
+ fn help(&self) -> Option<&'e str> { self.b.help }
+ fn long_help(&self) -> Option<&'e str> { self.b.long_help }
+ 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())
+ }
+ fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
+ fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
+ self.v
+ .env
+ .as_ref()
+ .map(|&(key, ref value)| (key, value.as_ref()))
+ }
+ fn longest_filter(&self) -> bool { true }
+ fn aliases(&self) -> Option<Vec<&'e str>> { None }
+}
+
+impl<'n, 'e> DispOrder for PosBuilder<'n, 'e> {
+ fn disp_ord(&self) -> usize { self.index as usize }
+}
+
+impl<'n, 'e> PartialEq for PosBuilder<'n, 'e> {
+ fn eq(&self, other: &PosBuilder<'n, 'e>) -> bool { self.b == other.b }
+}
+
+#[cfg(test)]
+mod test {
+ use args::settings::ArgSettings;
+ use super::PosBuilder;
+ use map::VecMap;
+
+ #[test]
+ fn display_mult() {
+ let mut p = PosBuilder::new("pos", 1);
+ p.b.settings.set(ArgSettings::Multiple);
+
+ assert_eq!(&*format!("{}", p), "<pos>...");
+ }
+
+ #[test]
+ fn display_required() {
+ let mut p2 = PosBuilder::new("pos", 1);
+ p2.b.settings.set(ArgSettings::Required);
+
+ assert_eq!(&*format!("{}", p2), "<pos>");
+ }
+
+ #[test]
+ fn display_val_names() {
+ let mut p2 = PosBuilder::new("pos", 1);
+ let mut vm = VecMap::new();
+ vm.insert(0, "file1");
+ vm.insert(1, "file2");
+ p2.v.val_names = Some(vm);
+
+ assert_eq!(&*format!("{}", p2), "<file1> <file2>");
+ }
+
+ #[test]
+ fn display_val_names_req() {
+ let mut p2 = PosBuilder::new("pos", 1);
+ p2.b.settings.set(ArgSettings::Required);
+ let mut vm = VecMap::new();
+ vm.insert(0, "file1");
+ vm.insert(1, "file2");
+ p2.v.val_names = Some(vm);
+
+ assert_eq!(&*format!("{}", p2), "<file1> <file2>");
+ }
+}
diff --git a/clap/src/args/arg_builder/switched.rs b/clap/src/args/arg_builder/switched.rs
new file mode 100644
index 0000000..224b2f2
--- /dev/null
+++ b/clap/src/args/arg_builder/switched.rs
@@ -0,0 +1,38 @@
+use Arg;
+
+#[derive(Debug)]
+pub struct Switched<'b> {
+ pub short: Option<char>,
+ pub long: Option<&'b str>,
+ pub aliases: Option<Vec<(&'b str, bool)>>, // (name, visible)
+ pub disp_ord: usize,
+ pub unified_ord: usize,
+}
+
+impl<'e> Default for Switched<'e> {
+ fn default() -> Self {
+ Switched {
+ short: None,
+ long: None,
+ aliases: None,
+ disp_ord: 999,
+ unified_ord: 999,
+ }
+ }
+}
+
+impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for Switched<'e> {
+ fn from(a: &'z Arg<'n, 'e>) -> Self { a.s.clone() }
+}
+
+impl<'e> Clone for Switched<'e> {
+ fn clone(&self) -> Self {
+ Switched {
+ short: self.short,
+ long: self.long,
+ aliases: self.aliases.clone(),
+ disp_ord: self.disp_ord,
+ unified_ord: self.unified_ord,
+ }
+ }
+}
diff --git a/clap/src/args/arg_builder/valued.rs b/clap/src/args/arg_builder/valued.rs
new file mode 100644
index 0000000..d70854d
--- /dev/null
+++ b/clap/src/args/arg_builder/valued.rs
@@ -0,0 +1,67 @@
+use std::rc::Rc;
+use std::ffi::{OsStr, OsString};
+
+use map::VecMap;
+
+use Arg;
+
+#[allow(missing_debug_implementations)]
+#[derive(Clone)]
+pub struct Valued<'a, 'b>
+where
+ 'a: 'b,
+{
+ pub possible_vals: Option<Vec<&'b str>>,
+ pub val_names: Option<VecMap<&'b str>>,
+ pub num_vals: Option<u64>,
+ pub max_vals: Option<u64>,
+ pub min_vals: Option<u64>,
+ pub validator: Option<Rc<Fn(String) -> Result<(), String>>>,
+ pub validator_os: Option<Rc<Fn(&OsStr) -> Result<(), OsString>>>,
+ pub val_delim: Option<char>,
+ pub default_val: Option<&'b OsStr>,
+ pub default_vals_ifs: Option<VecMap<(&'a str, Option<&'b OsStr>, &'b OsStr)>>,
+ pub env: Option<(&'a OsStr, Option<OsString>)>,
+ pub terminator: Option<&'b str>,
+}
+
+impl<'n, 'e> Default for Valued<'n, 'e> {
+ fn default() -> Self {
+ Valued {
+ possible_vals: None,
+ num_vals: None,
+ min_vals: None,
+ max_vals: None,
+ val_names: None,
+ validator: None,
+ validator_os: None,
+ val_delim: None,
+ default_val: None,
+ default_vals_ifs: None,
+ env: None,
+ terminator: None,
+ }
+ }
+}
+
+impl<'n, 'e> Valued<'n, 'e> {
+ pub fn fill_in(&mut self) {
+ if let Some(ref vec) = self.val_names {
+ if vec.len() > 1 {
+ self.num_vals = Some(vec.len() as u64);
+ }
+ }
+ }
+}
+
+impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for Valued<'n, 'e> {
+ fn from(a: &'z Arg<'n, 'e>) -> Self {
+ let mut v = a.v.clone();
+ if let Some(ref vec) = a.v.val_names {
+ if vec.len() > 1 {
+ v.num_vals = Some(vec.len() as u64);
+ }
+ }
+ v
+ }
+}