mirror of
https://github.com/clap-rs/clap
synced 2024-11-10 14:54:15 +00:00
wip: breaking down Arg into types
This commit is contained in:
parent
c994cef85e
commit
df8aa6b2ee
17 changed files with 202 additions and 97 deletions
|
@ -50,4 +50,7 @@ impl<'help> Aliases<'help> {
|
|||
pub fn add_visible<S: AsRef<&'help str>>(&mut self, name: S) {
|
||||
self.0.push(Alias::new(name));
|
||||
}
|
||||
pub fn add_hidden<S: AsRef<&'help str>>(&mut self, name: S) {
|
||||
self.0.push(Alias::new(name).hidden());
|
||||
}
|
||||
}
|
13
src/build/arg/default_values.rs
Normal file
13
src/build/arg/default_values.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
pub struct DefaultValue<'help> {
|
||||
value: &'help str,
|
||||
}
|
||||
|
||||
pub struct ConditionalDefault<'help> {
|
||||
value: DefaultValue<'help>,
|
||||
other_arg: Option<u64>,
|
||||
other_value: Option<&'help str>,
|
||||
}
|
||||
|
||||
pub struct DefaultValues<'help> {
|
||||
defaults: Vec<ConditionalDefault<'help>>,
|
||||
}
|
4
src/build/arg/delimiter.rs
Normal file
4
src/build/arg/delimiter.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
pub struct Delimiter {
|
||||
delimiter: char,
|
||||
required: bool
|
||||
}
|
13
src/build/arg/display_order.rs
Normal file
13
src/build/arg/display_order.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
pub struct DisplayOrder(usize);
|
||||
|
||||
impl Default for DisplayOrder {
|
||||
fn default() -> Self {
|
||||
DisplayOrder(999)
|
||||
}
|
||||
}
|
||||
|
||||
impl DisplayOrder {
|
||||
pub fn new() -> Self {
|
||||
DisplayOrder::default()
|
||||
}
|
||||
}
|
9
src/build/arg/filter.rs
Normal file
9
src/build/arg/filter.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
pub struct Filter {
|
||||
terminator: Terminator,
|
||||
#[doc(hidden)]
|
||||
validator: Option<Validator>,
|
||||
#[doc(hidden)]
|
||||
validator_os: Option<ValidatorOs>,
|
||||
possible_values: PossibleValues,
|
||||
hyphen_values: bool,
|
||||
}
|
8
src/build/arg/help_message.rs
Normal file
8
src/build/arg/help_message.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
pub struct HelpMessage<'help> {
|
||||
short_message: &'help str,
|
||||
long_message: &'help str,
|
||||
value_names: VecMap<ValueName>,
|
||||
display_order: DisplayOrder,
|
||||
unified_order: DisplayOrder, // @TODO remove?
|
||||
heading: &'help str, // @TODO multiple?
|
||||
}
|
32
src/build/arg/key.rs
Normal file
32
src/build/arg/key.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use build::arg::{Short, Long, Position};
|
||||
|
||||
pub struct Key<'help> {
|
||||
short: Option<Short>,
|
||||
long: Option<Long<'help>>,
|
||||
index: Option<Position>
|
||||
}
|
||||
|
||||
impl<'help> Key<'help> {
|
||||
pub fn new() -> Self {
|
||||
Key { short: None, long: None, index: None }
|
||||
}
|
||||
|
||||
pub fn is_positional(&self) -> bool {
|
||||
self.index.is_some() || !self.has_switch()
|
||||
}
|
||||
|
||||
pub fn has_switch(&self) -> bool {
|
||||
self.short.is_some() || self.long.is_some()
|
||||
}
|
||||
|
||||
pub fn short(&mut self, short: char) {
|
||||
self.short.replace(short);
|
||||
}
|
||||
|
||||
pub fn long(&mut self, l: &'help str) {
|
||||
self.long.add_long(l);
|
||||
}
|
||||
pub fn hidden_long(&mut self, l: &'help str) {
|
||||
self.long.add_hidden_long(l);
|
||||
}
|
||||
}
|
14
src/build/arg/long.rs
Normal file
14
src/build/arg/long.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use build::Aliases;
|
||||
|
||||
pub struct Long<'help> {
|
||||
aliases: Aliases<'help>
|
||||
}
|
||||
|
||||
impl<'help> Long<'help> {
|
||||
pub fn long(&mut self, l: &'help str) {
|
||||
self.aliases.add_visible(l.trim_left_matches(|c| c == '-'));
|
||||
}
|
||||
pub fn hidden_long(&mut self, l: &'help str) {
|
||||
self.aliases.add_hidden(l.trim_left_matches(|c| c == '-'));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
// @TODO @p2 @docs remove Arg::setting(foo) in examples, we are sticking with Arg::foo(true) isntead
|
||||
|
||||
mod settings;
|
||||
mod key;
|
||||
mod short;
|
||||
mod long;
|
||||
pub use self::settings::{ArgFlags, ArgSettings};
|
||||
|
||||
// Std
|
||||
|
@ -25,6 +28,7 @@ use yaml_rust;
|
|||
use build::UsageParser;
|
||||
use INTERNAL_ERROR_MSG;
|
||||
use util::hash;
|
||||
use self::key::Key;
|
||||
|
||||
type Validator = Rc<Fn(String) -> Result<(), String>>;
|
||||
type ValidatorOs = Rc<Fn(&OsStr) -> Result<(), String>>;
|
||||
|
@ -57,61 +61,11 @@ pub struct Arg<'help> {
|
|||
#[doc(hidden)]
|
||||
pub id: u64,
|
||||
#[doc(hidden)]
|
||||
pub help: Option<&'help str>,
|
||||
#[doc(hidden)]
|
||||
pub long_help: Option<&'help str>,
|
||||
#[doc(hidden)]
|
||||
pub blacklist: Option<Vec<u64>>,
|
||||
key: Key<'help>,
|
||||
#[doc(hidden)]
|
||||
pub settings: ArgFlags,
|
||||
#[doc(hidden)]
|
||||
pub r_unless: Option<Vec<u64>>,
|
||||
#[doc(hidden)]
|
||||
pub overrides: Option<Vec<u64>>,
|
||||
#[doc(hidden)]
|
||||
pub requires: Option<Vec<(Option<&'help str>, u64)>>,
|
||||
#[doc(hidden)]
|
||||
pub short: Option<char>,
|
||||
#[doc(hidden)]
|
||||
pub long: Option<&'help str>,
|
||||
#[doc(hidden)]
|
||||
pub aliases: Option<Vec<(&'help str, bool)>>, // (name, visible)
|
||||
#[doc(hidden)]
|
||||
pub disp_ord: usize,
|
||||
#[doc(hidden)]
|
||||
pub unified_ord: usize,
|
||||
#[doc(hidden)]
|
||||
pub possible_vals: Option<Vec<&'help str>>,
|
||||
#[doc(hidden)]
|
||||
pub val_names: Option<VecMap<&'help str>>,
|
||||
#[doc(hidden)]
|
||||
pub num_vals: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub num_vals_per_occ: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub max_vals: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub min_vals: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub validator: Option<Validator>,
|
||||
#[doc(hidden)]
|
||||
pub validator_os: Option<ValidatorOs>,
|
||||
#[doc(hidden)]
|
||||
pub val_delim: Option<char>,
|
||||
#[doc(hidden)]
|
||||
pub default_val: Option<&'help OsStr>,
|
||||
#[doc(hidden)]
|
||||
pub default_vals_ifs: Option<VecMap<(u64, Option<&'help OsStr>, &'help OsStr)>>,
|
||||
#[doc(hidden)]
|
||||
pub env: Option<(&'help OsStr, Option<OsString>)>,
|
||||
#[doc(hidden)]
|
||||
pub terminator: Option<&'help str>,
|
||||
#[doc(hidden)]
|
||||
pub index: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub r_ifs: Option<Vec<(u64, &'help str)>>,
|
||||
#[doc(hidden)]
|
||||
pub help_heading: Option<&'help str>,
|
||||
}
|
||||
|
||||
impl<'help> Arg<'help> {
|
||||
|
@ -144,9 +98,7 @@ impl<'help> Arg<'help> {
|
|||
r_unless: None,
|
||||
overrides: None,
|
||||
requires: None,
|
||||
short: None,
|
||||
long: None,
|
||||
aliases: None,
|
||||
key: Key::new(),
|
||||
possible_vals: None,
|
||||
val_names: None,
|
||||
num_vals: None,
|
||||
|
@ -200,7 +152,7 @@ impl<'help> Arg<'help> {
|
|||
/// ```
|
||||
/// [`short`]: ./struct.Arg.html#method.short
|
||||
pub fn short(mut self, s: char) -> Self {
|
||||
self.short = Some(s);
|
||||
self.key.short(s);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -240,7 +192,7 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(m.is_present("cfg"));
|
||||
/// ```
|
||||
pub fn long(mut self, l: &'help str) -> Self {
|
||||
self.long = Some(l.trim_left_matches(|c| c == '-'));
|
||||
self.key.long(l);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -266,11 +218,7 @@ impl<'help> Arg<'help> {
|
|||
/// ```
|
||||
/// [`Arg`]: ./struct.Arg.html
|
||||
pub fn alias<S: Into<&'help str>>(mut self, name: S) -> Self {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
als.push((name.into(), false));
|
||||
} else {
|
||||
self.aliases = Some(vec![(name.into(), false)]);
|
||||
}
|
||||
self.key.hidden_long(s.into());
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -296,12 +244,8 @@ impl<'help> Arg<'help> {
|
|||
/// ```
|
||||
/// [`Arg`]: ./struct.Arg.html
|
||||
pub fn aliases(mut self, names: &[&'help str]) -> Self {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
for &n in names {
|
||||
als.push((n, false));
|
||||
}
|
||||
} else {
|
||||
self.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>());
|
||||
for &n in names {
|
||||
self.key.hidden_long(n);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -327,11 +271,7 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
/// [`App::alias`]: ./struct.Arg.html#method.alias
|
||||
pub fn visible_alias<S: Into<&'help str>>(mut self, name: S) -> Self {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
als.push((name.into(), true));
|
||||
} else {
|
||||
self.aliases = Some(vec![(name.into(), true)]);
|
||||
}
|
||||
self.key.long(s.into());
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -354,12 +294,8 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
/// [`App::aliases`]: ./struct.Arg.html#method.aliases
|
||||
pub fn visible_aliases(mut self, names: &[&'help str]) -> Self {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
for &n in names {
|
||||
als.push((n, true));
|
||||
}
|
||||
} else {
|
||||
self.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>());
|
||||
for &n in names {
|
||||
self.key.long(n);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -3883,15 +3819,19 @@ impl<'help> Arg<'help> {
|
|||
self
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _build(&mut self) {
|
||||
fn set_default_delimiter(&mut self) {
|
||||
if (self.is_set(ArgSettings::UseValueDelimiter)
|
||||
|| self.is_set(ArgSettings::RequireDelimiter))
|
||||
&& self.val_delim.is_none()
|
||||
{
|
||||
self.val_delim = Some(',');
|
||||
}
|
||||
if self.index.is_some() || (self.short.is_none() && self.long.is_none()) {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _build(&mut self) {
|
||||
self.set_default_delimiter();
|
||||
if self.key.is_positional() {
|
||||
if self.max_vals.is_some()
|
||||
|| self.min_vals.is_some()
|
||||
|| (self.num_vals.is_some() && self.num_vals.unwrap() > 1)
|
||||
|
@ -3917,12 +3857,14 @@ impl<'help> Arg<'help> {
|
|||
pub fn unsetb(&mut self, s: ArgSettings) { self.settings.unset(s); }
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn has_switch(&self) -> bool { self.short.is_some() || self.long.is_some() }
|
||||
pub fn has_switch(&self) -> bool { self.key.has_switch() }
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn longest_filter(&self) -> bool {
|
||||
self.is_set(ArgSettings::TakesValue) || self.long.is_some() || self.short.is_none()
|
||||
}
|
||||
// We should probably figure out this the hard way in the help display, or find a better way
|
||||
// to encapsulate this.
|
||||
// #[doc(hidden)]
|
||||
// pub fn longest_filter(&self) -> bool {
|
||||
// self.is_set(ArgSettings::TakesValue) || self.long.is_some() || self.short.is_none()
|
||||
// }
|
||||
|
||||
// Used for positionals when printing
|
||||
#[doc(hidden)]
|
||||
|
@ -3961,7 +3903,7 @@ impl<'help> PartialEq for Arg<'help> {
|
|||
|
||||
impl<'help> Display for Arg<'help> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
if self.index.is_some() || (self.long.is_none() && self.short.is_none()) {
|
||||
if self.key.is_positional() {
|
||||
// Positional
|
||||
let mut delim = String::new();
|
||||
delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
|
||||
|
@ -4063,13 +4005,32 @@ impl<'help> fmt::Debug for Arg<'help> {
|
|||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
write!(
|
||||
f,
|
||||
"Arg {{ id: {:?}, help: {:?}, long_help: {:?}, conflicts_with: {:?}, \
|
||||
settings: {:?}, required_unless: {:?}, overrides_with: {:?}, \
|
||||
requires: {:?}, requires_ifs: {:?}, short: {:?}, index: {:?}, long: {:?}, \
|
||||
aliases: {:?}, possible_values: {:?}, value_names: {:?}, number_of_values: {:?}, \
|
||||
max_values: {:?}, min_values: {:?}, value_delimiter: {:?}, default_value_ifs: {:?}, \
|
||||
value_terminator: {:?}, display_order: {:?}, env: {:?}, unified_ord: {:?}, \
|
||||
default_value: {:?}, validator: {}, validator_os: {} \
|
||||
"Arg {{ \
|
||||
id: {:?}, \
|
||||
help: {:?}, \
|
||||
long_help: {:?}, \
|
||||
conflicts_with: {:?}, \
|
||||
settings: {:?}, \
|
||||
required_unless: {:?}, \
|
||||
overrides_with: {:?}, \
|
||||
requires: {:?}, \
|
||||
requires_ifs: {:?}, \
|
||||
key: {:?}, \
|
||||
index: {:?}, \
|
||||
possible_values: {:?}, \
|
||||
value_names: {:?}, \
|
||||
number_of_values: {:?}, \
|
||||
max_values: {:?}, \
|
||||
min_values: {:?}, \
|
||||
value_delimiter: {:?}, \
|
||||
default_value_ifs: {:?}, \
|
||||
value_terminator: {:?}, \
|
||||
display_order: {:?}, \
|
||||
env: {:?}, \
|
||||
unified_ord: {:?}, \
|
||||
default_value: {:?}, \
|
||||
validator: {}, \
|
||||
validator_os: {} \
|
||||
}}",
|
||||
self.id,
|
||||
self.help,
|
||||
|
@ -4080,10 +4041,8 @@ impl<'help> fmt::Debug for Arg<'help> {
|
|||
self.overrides,
|
||||
self.requires,
|
||||
self.r_ifs,
|
||||
self.short,
|
||||
self.key,
|
||||
self.index,
|
||||
self.long,
|
||||
self.aliases,
|
||||
self.possible_vals,
|
||||
self.val_names,
|
||||
self.num_vals,
|
||||
|
|
5
src/build/arg/occurrence.rs
Normal file
5
src/build/arg/occurrence.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
#[derive(Default, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Occurrence {
|
||||
min: u64,
|
||||
max: u64
|
||||
}
|
3
src/build/arg/position.rs
Normal file
3
src/build/arg/position.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub struct Position {
|
||||
index: u64
|
||||
}
|
7
src/build/arg/possible_values.rs
Normal file
7
src/build/arg/possible_values.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
pub struct PossibleValue<'help> {
|
||||
value: &'help str,
|
||||
}
|
||||
|
||||
pub struct PossibleValues<'help> {
|
||||
values: Vec<PossibleValue<'help>>
|
||||
}
|
3
src/build/arg/short.rs
Normal file
3
src/build/arg/short.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub struct Short {
|
||||
short: char
|
||||
}
|
4
src/build/arg/terminator.rs
Normal file
4
src/build/arg/terminator.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
pub struct Terminator {
|
||||
terminator: char,
|
||||
required: bool,
|
||||
}
|
17
src/build/arg/validation_rules.rs
Normal file
17
src/build/arg/validation_rules.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
pub struct Rule<'help> {
|
||||
other_arg: u64,
|
||||
self_value: Option<&'help str>,
|
||||
other_value: Option<&'help str>,
|
||||
}
|
||||
|
||||
pub struct Rules<'help> {
|
||||
rules: Vec<Rule<'help>>,
|
||||
}
|
||||
|
||||
pub struct ValidationRules<'help> {
|
||||
occurrence: Occurrence,
|
||||
conflicts: Rules<'help>,
|
||||
requirements: Rules<'help>,
|
||||
overrides: Rules<'help>,
|
||||
requirements_unless: Rules<'help>,
|
||||
}
|
8
src/build/arg/value.rs
Normal file
8
src/build/arg/value.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
pub struct Value<'help> {
|
||||
defaults: Option<DefaultValues>,
|
||||
name: Option<&'help str>,
|
||||
filter: Filter,
|
||||
occurrence: Occurrence,
|
||||
requires_equals: bool,
|
||||
delimiter: Delimiter,
|
||||
}
|
3
src/build/arg/value_name.rs
Normal file
3
src/build/arg/value_name.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub struct ValueName<'help> {
|
||||
name: &'help str,
|
||||
}
|
Loading…
Reference in a new issue