aboutsummaryrefslogtreecommitdiff
path: root/clap/src/args/arg_builder/option.rs
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/option.rs
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/option.rs')
-rw-r--r--clap/src/args/arg_builder/option.rs244
1 files changed, 244 insertions, 0 deletions
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>");
+ }
+}