diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2020-01-07 11:18:04 +0000 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2020-01-08 09:20:25 -0800 |
commit | 5e20a29b4fdc8a2d442d1093681b396dcb4b816b (patch) | |
tree | 55ab083fa8999d2ccbb5e921c1ffe52560dca152 /clap/src/args/arg_builder | |
parent | 203e691f46d591a2cc8acdfd850fa9f5b0fb8a98 (diff) | |
download | nitrocli-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.rs | 38 | ||||
-rw-r--r-- | clap/src/args/arg_builder/flag.rs | 159 | ||||
-rw-r--r-- | clap/src/args/arg_builder/mod.rs | 13 | ||||
-rw-r--r-- | clap/src/args/arg_builder/option.rs | 244 | ||||
-rw-r--r-- | clap/src/args/arg_builder/positional.rs | 229 | ||||
-rw-r--r-- | clap/src/args/arg_builder/switched.rs | 38 | ||||
-rw-r--r-- | clap/src/args/arg_builder/valued.rs | 67 |
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 + } +} |