Repository: clap-rs/clap
Pull request #2339 (2021-02-11 00:13:40)

Remove Arg::settings to be consistent with App
<!--
If your PR closes some issues, please write `Closes #XXXX`
where `XXXX` is the number of the issue you want to fix.
Each issue goes on its own line.
-->



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e0660b25..2e69b014 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,9 @@ TODO: `cargo`, `std` features
 
 #### BREAKING CHANGES
 
+* **Removed Methods**
+  * **Arg**
+    * `Arg::settings` in favor of `Arg::setting(Setting1 | Setting2)`
 * **Renamed Settings**
   * `AppSettings::DisableHelpFlags` => `AppSettings::DisableHelpFlag`
   * `AppSettings::DisableVersion` => `AppSettings::DisableVersionFlag`
@@ -196,6 +199,7 @@ TODO: `cargo`, `std` features
     * `Arg::multiple_values`
     * `Arg::multiple_occurrences`
     * `Arg::help_heading`
+    * `Arg::settings`
 * **Added Settings**
   * `AppSettings::HelpRequired`
   * `AppSettings::NoAutoHelp`
diff --git a/benches/03_complex.rs b/benches/03_complex.rs
index 04979b42..4e152dd3 100644
--- a/benches/03_complex.rs
+++ b/benches/03_complex.rs
@@ -67,7 +67,7 @@ pub fn build_from_builder(c: &mut Criterion) {
                         .about("tests flags")
                         .long("flag")
                         .global(true)
-                        .settings(&[ArgSettings::MultipleOccurrences]),
+                        .setting(ArgSettings::MultipleOccurrences),
                 )
                 .arg(
                     Arg::new("flag2")
diff --git a/benches/04_new_help.rs b/benches/04_new_help.rs
index f245111e..3b2f7149 100644
--- a/benches/04_new_help.rs
+++ b/benches/04_new_help.rs
@@ -112,11 +112,9 @@ fn app_example7<'c>() -> App<'c> {
         .arg(
             Arg::new("input")
                 .about("the input file to use")
-                .settings(&[
-                    ArgSettings::MultipleValues,
-                    ArgSettings::MultipleOccurrences,
-                    ArgSettings::Required,
-                ])
+                .setting(ArgSettings::MultipleValues)
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::Required)
                 .short('i')
                 .long("input")
                 .requires("config")
@@ -131,11 +129,9 @@ fn app_example8<'c>() -> App<'c> {
         .arg(
             Arg::new("input")
                 .about("the input file to use")
-                .settings(&[
-                    ArgSettings::MultipleValues,
-                    ArgSettings::MultipleOccurrences,
-                    ArgSettings::Required,
-                ])
+                .setting(ArgSettings::MultipleValues)
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::Required)
                 .short('i')
                 .long("input")
                 .requires("config")
diff --git a/benches/05_ripgrep.rs b/benches/05_ripgrep.rs
index ebde55e2..866e8e95 100644
--- a/benches/05_ripgrep.rs
+++ b/benches/05_ripgrep.rs
@@ -332,11 +332,9 @@ where
         .arg(
             flag("regexp")
                 .short('e')
-                .settings(&[
-                    ArgSettings::AllowHyphenValues,
-                    ArgSettings::MultipleOccurrences,
-                    ArgSettings::TakesValue,
-                ])
+                .setting(ArgSettings::AllowHyphenValues)
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::TakesValue)
                 .value_name("pattern"),
         )
         .arg(
@@ -358,13 +356,15 @@ where
         .arg(
             flag("colors")
                 .value_name("SPEC")
-                .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue]),
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::TakesValue),
         )
         .arg(flag("fixed-strings").short('F'))
         .arg(
             flag("glob")
                 .short('g')
-                .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::TakesValue)
                 .value_name("GLOB"),
         )
         .arg(flag("ignore-case").short('i'))
@@ -374,13 +374,15 @@ where
         .arg(
             flag("type")
                 .short('t')
-                .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::TakesValue)
                 .value_name("TYPE"),
         )
         .arg(
             flag("type-not")
                 .short('T')
-                .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::TakesValue)
                 .value_name("TYPE"),
         )
         .arg(
diff --git a/benches/06_rustup.rs b/benches/06_rustup.rs
index 907ad702..e056aa26 100644
--- a/benches/06_rustup.rs
+++ b/benches/06_rustup.rs
@@ -262,11 +262,12 @@ fn build_cli() -> App<'static> {
                 .after_help(RUN_HELP)
                 .setting(AppSettings::TrailingVarArg)
                 .arg(Arg::new("toolchain").setting(ArgSettings::Required))
-                .arg(Arg::new("command").settings(&[
-                    ArgSettings::Required,
-                    ArgSettings::MultipleValues,
-                    ArgSettings::MultipleOccurrences,
-                ])),
+                .arg(
+                    Arg::new("command")
+                        .setting(ArgSettings::Required)
+                        .setting(ArgSettings::MultipleValues)
+                        .setting(ArgSettings::MultipleOccurrences),
+                ),
         )
         .subcommand(
             App::new("which")
diff --git a/clap.schema.json b/clap.schema.json
index 4fa922bd..80997e25 100644
--- a/clap.schema.json
+++ b/clap.schema.json
@@ -51,7 +51,6 @@
   "definitions": {
     "arg": {
       "type": "object",
-
       "properties": {
         "about": {
           "type": "string"
@@ -315,7 +314,6 @@
       "type": "string"
     }
   },
-
   "type": "object",
   "TODO:": "set 'name' as required",
   "properties": {
diff --git a/examples/16_app_settings.rs b/examples/16_app_settings.rs
index 68c06f32..11e3c5f0 100644
--- a/examples/16_app_settings.rs
+++ b/examples/16_app_settings.rs
@@ -2,9 +2,8 @@ use clap::{App, AppSettings};
 
 fn main() {
     // You can use AppSettings to change the application level behavior of clap. .setting() function
-    // of App struct takes AppSettings enum as argument. There is also .settings() function which
-    // takes slice of AppSettings enum.  You can learn more about AppSettings in the documentation,
-    // which also has examples on each setting.
+    // of App struct takes AppSettings enum as argument. You can learn more about AppSettings in the
+    // documentation, which also has examples on each setting.
     //
     // This example will only show usage of one AppSettings setting. See documentation for more
     // information.
diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs
index a5a0c2eb..6b2c93bf 100644
--- a/src/build/app/mod.rs
+++ b/src/build/app/mod.rs
@@ -918,7 +918,6 @@ impl<'help> App<'help> {
     /// # ;
     /// ```
     /// [`AppSettings`]: ./enum.AppSettings.html
-    /// [global]: ./struct.App.html#method.global_setting
     #[inline]
     pub fn unset_setting(mut self, setting: AppSettings) -> Self {
         self.settings.unset(setting);
diff --git a/src/build/arg/mod.rs b/src/build/arg/mod.rs
index 43df7466..3d0f70ad 100644
--- a/src/build/arg/mod.rs
+++ b/src/build/arg/mod.rs
@@ -3058,10 +3058,11 @@ impl<'help> Arg<'help> {
     /// # use clap::{App, Arg, ArgSettings};
     /// let res = App::new("prog")
     ///     .arg(Arg::new("cfg")
-    ///         .settings(&[ArgSettings::Required, ArgSettings::TakesValue])
+    ///         .setting(ArgSettings::Required)
+    ///         .setting(ArgSettings::TakesValue)
     ///         .long("config"))
     ///     .try_get_matches_from(vec![
-    ///         "prog", "--config", "file.conf"
+    ///         "prog", "--config", "file.conf",
     ///     ]);
     ///
     /// assert!(res.is_ok());
@@ -3073,7 +3074,8 @@ impl<'help> Arg<'help> {
     /// # use clap::{App, Arg, ArgSettings, ErrorKind};
     /// let res = App::new("prog")
     ///     .arg(Arg::new("cfg")
-    ///         .settings(&[ArgSettings::Required, ArgSettings::TakesValue])
+    ///         .setting(ArgSettings::Required)
+    ///         .setting(ArgSettings::TakesValue)
     ///         .long("config"))
     ///     .try_get_matches_from(vec![
     ///         "prog"
@@ -3340,7 +3342,8 @@ impl<'help> Arg<'help> {
     /// let delims = App::new("prog")
     ///     .arg(Arg::new("opt")
     ///         .short('o')
-    ///         .settings(&[ArgSettings::RequireDelimiter, ArgSettings::MultipleValues]))
+    ///         .setting(ArgSettings::RequireDelimiter)
+    ///         .setting(ArgSettings::MultipleValues))
     ///     .get_matches_from(vec![
     ///         "prog", "-o", "val1,val2,val3",
     ///     ]);
@@ -3545,7 +3548,8 @@ impl<'help> Arg<'help> {
     ///     .arg(Arg::new("option")
     ///         .short('o')
     ///         .long("--option")
-    ///         .settings(&[ArgSettings::IgnoreCase, ArgSettings::MultipleValues])
+    ///         .setting(ArgSettings::IgnoreCase)
+    ///         .setting(ArgSettings::MultipleValues)
     ///         .possible_value("test123")
     ///         .possible_value("test321"))
     ///     .get_matches_from(vec![
@@ -3713,7 +3717,8 @@ impl<'help> Arg<'help> {
     ///     .arg(Arg::new("opt")
     ///         .long("long-option-flag")
     ///         .short('o')
-    ///         .settings(&[ArgSettings::TakesValue, ArgSettings::NextLineHelp])
+    ///         .setting(ArgSettings::TakesValue)
+    ///         .setting(ArgSettings::NextLineHelp)
     ///         .value_names(&["value1", "value2"])
     ///         .about("Some really long help and complex\n\
     ///                help that makes more sense to be\n\
@@ -3888,7 +3893,8 @@ impl<'help> Arg<'help> {
     /// # use clap::{App, Arg, ArgSettings};
     /// let m = App::new("prog")
     ///     .arg(Arg::new("file")
-    ///         .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+    ///         .setting(ArgSettings::MultipleOccurrences)
+    ///         .setting(ArgSettings::TakesValue)
     ///         .short('F'))
     ///     .arg(Arg::new("word")
     ///         .index(1))
@@ -3908,7 +3914,8 @@ impl<'help> Arg<'help> {
     /// # use clap::{App, Arg, ErrorKind, ArgSettings};
     /// let res = App::new("prog")
     ///     .arg(Arg::new("file")
-    ///         .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+    ///         .setting(ArgSettings::MultipleOccurrences)
+    ///         .setting(ArgSettings::TakesValue)
     ///         .short('F'))
     ///     .arg(Arg::new("word")
     ///         .index(1))
@@ -4032,7 +4039,8 @@ impl<'help> Arg<'help> {
     /// # use clap::{App, Arg, ArgSettings};
     /// let m = App::new("prog")
     ///     .arg(Arg::new("file")
-    ///         .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+    ///         .setting(ArgSettings::MultipleOccurrences)
+    ///         .setting(ArgSettings::TakesValue)
     ///         .short('F'))
     ///     .get_matches_from(vec![
     ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3"
@@ -4252,32 +4260,42 @@ impl<'help> Arg<'help> {
         self.settings.is_set(s)
     }
 
-    /// Sets one of the [`ArgSettings`] settings for the argument
+    /// Enables a single setting for the current (this `Arg` instance) argument.
+    ///
+    /// See [`ArgSettings`] for a full list of possibilities and examples.
+    ///
+    /// # Examples
     ///
+    /// ```no_run
+    /// # use clap::{Arg, ArgSettings};
+    /// Arg::new("config")
+    ///     .setting(ArgSettings::Required)
+    ///     .setting(ArgSettings::TakesValue)
+    /// # ;
+    /// ```
     /// [`ArgSettings`]: ./enum.ArgSettings.html
     #[inline]
-    pub fn setting(mut self, s: ArgSettings) -> Self {
-        self.set_mut(s);
+    pub fn setting(mut self, setting: ArgSettings) -> Self {
+        self.settings.set(setting);
         self
     }
 
-    // @TODO @docs @v3-beta: write better docs as ArgSettings is now critical
-    /// Sets multiple [`ArgSettings`] for the argument
+    /// Disables a single setting for the current (this `Arg` instance) argument.
     ///
-    /// [`ArgSettings`]: ./enum.ArgSettings.html
-    pub fn settings(mut self, settings: &[ArgSettings]) -> Self {
-        for s in settings {
-            self.settings.set(*s);
-        }
-        self
-    }
-
-    /// Unsets one of the [`ArgSettings`] for the argument
+    /// See [`ArgSettings`] for a full list of possibilities and examples.
     ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// # use clap::{Arg, ArgSettings};
+    /// Arg::new("config")
+    ///     .unset_setting(ArgSettings::Required)
+    /// # ;
+    /// ```
     /// [`ArgSettings`]: ./enum.ArgSettings.html
     #[inline]
-    pub fn unset_setting(mut self, s: ArgSettings) -> Self {
-        self.unset_mut(s);
+    pub fn unset_setting(mut self, setting: ArgSettings) -> Self {
+        self.settings.unset(setting);
         self
     }
 
@@ -4315,7 +4333,7 @@ impl<'help> Arg<'help> {
     /// # ;
     /// ```
     pub fn value_hint(mut self, value_hint: ValueHint) -> Self {
-        self.set_mut(ArgSettings::TakesValue);
+        self.settings.set(ArgSettings::TakesValue);
         self.value_hint = value_hint;
         self
     }
@@ -4334,22 +4352,14 @@ impl<'help> Arg<'help> {
                 || self.min_vals.is_some()
                 || (self.num_vals.is_some() && self.num_vals.unwrap() > 1)
             {
-                self.set_mut(ArgSettings::MultipleValues);
-                self.set_mut(ArgSettings::MultipleOccurrences);
+                self.settings.set(ArgSettings::MultipleValues);
+                self.settings.set(ArgSettings::MultipleOccurrences);
             }
         } else if self.is_set(ArgSettings::TakesValue) && self.val_names.len() > 1 {
             self.num_vals = Some(self.val_names.len() as u64);
         }
     }
 
-    pub(crate) fn set_mut(&mut self, s: ArgSettings) {
-        self.settings.set(s);
-    }
-
-    pub(crate) fn unset_mut(&mut self, s: ArgSettings) {
-        self.settings.unset(s);
-    }
-
     pub(crate) fn has_switch(&self) -> bool {
         self.short.is_some() || self.long.is_some()
     }
@@ -4524,7 +4534,7 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
                 "required_unless_present_any" => yaml_vec!(a, v, required_unless_present_any),
                 "required_unless_present_all" => {
                     a = yaml_vec!(a, v, required_unless_present_all);
-                    a.set_mut(ArgSettings::RequiredUnlessAll);
+                    a.settings.set(ArgSettings::RequiredUnlessAll);
                     a
                 }
                 "visible_alias" => yaml_to_str!(a, v, visible_alias),
@@ -4870,16 +4880,16 @@ mod test {
 
     #[test]
     fn positiona_display_mult() {
-        let mut p = Arg::new("pos").index(1);
-        p.set_mut(ArgSettings::MultipleValues);
+        let p = Arg::new("pos")
+            .index(1)
+            .setting(ArgSettings::MultipleValues);
 
         assert_eq!(&*format!("{}", p), "<pos>...");
     }
 
     #[test]
     fn positional_display_required() {
-        let mut p2 = Arg::new("pos").index(1);
-        p2.settings.set(ArgSettings::Required);
+        let p2 = Arg::new("pos").index(1).setting(ArgSettings::Required);
 
         assert_eq!(&*format!("{}", p2), "<pos>");
     }
@@ -4897,8 +4907,7 @@ mod test {
 
     #[test]
     fn positional_display_val_names_req() {
-        let mut p2 = Arg::new("pos").index(1);
-        p2.settings.set(ArgSettings::Required);
+        let mut p2 = Arg::new("pos").index(1).setting(ArgSettings::Required);
         let mut vm = VecMap::new();
         vm.insert(0, "file1");
         vm.insert(1, "file2");
diff --git a/src/build/usage_parser.rs b/src/build/usage_parser.rs
index e5f07540..102abb5a 100644
--- a/src/build/usage_parser.rs
+++ b/src/build/usage_parser.rs
@@ -71,7 +71,7 @@ impl<'help> UsageParser<'help> {
         };
         if !arg.has_switch() && arg.is_set(ArgSettings::MultipleOccurrences) {
             // We had a positional and need to set mult vals too
-            arg.set_mut(ArgSettings::MultipleValues);
+            arg.settings.set(ArgSettings::MultipleValues);
         }
         debug!("UsageParser::parse: vals...{:?}", arg.val_names);
         arg
@@ -87,7 +87,7 @@ impl<'help> UsageParser<'help> {
             == b'<'
             && !self.explicit_name_set
         {
-            arg.set_mut(ArgSettings::Required);
+            arg.settings.set(ArgSettings::Required);
         }
         self.pos += 1;
         self.stop_at(name_end);
@@ -104,7 +104,7 @@ impl<'help> UsageParser<'help> {
         } else {
             debug!("UsageParser::name: setting val name...{}", name);
             if arg.val_names.is_empty() {
-                arg.set_mut(ArgSettings::TakesValue);
+                arg.settings.set(ArgSettings::TakesValue);
             }
             let len = arg.val_names.len();
             arg.val_names.insert(len, name);
@@ -183,9 +183,9 @@ impl<'help> UsageParser<'help> {
             if dot_counter == 3 {
                 debug!("UsageParser::multiple: setting multiple");
                 if arg.is_set(ArgSettings::TakesValue) {
-                    arg.set_mut(ArgSettings::MultipleValues);
+                    arg.settings.set(ArgSettings::MultipleValues);
                 }
-                arg.set_mut(ArgSettings::MultipleOccurrences);
+                arg.settings.set(ArgSettings::MultipleOccurrences);
                 self.prev = UsageToken::Multiple;
                 self.pos += 1;
                 break;
@@ -218,7 +218,7 @@ impl<'help> UsageParser<'help> {
             "UsageParser::default: setting default...\"{}\"",
             &self.usage[self.start..self.pos]
         );
-        arg.set_mut(ArgSettings::TakesValue);
+        arg.settings.set(ArgSettings::TakesValue);
         arg.default_vals = vec![std::ffi::OsStr::new(&self.usage[self.start..self.pos])];
         self.prev = UsageToken::Default;
     }


Test patch:
diff --git a/tests/help.rs b/tests/help.rs
index ec596a21..81827773 100644
--- a/tests/help.rs
+++ b/tests/help.rs
@@ -740,11 +740,9 @@ fn args_with_last_usage() {
         .arg(
             Arg::new("pass through args")
                 .about("Any arguments you wish to pass to the being profiled.")
-                .settings(&[
-                    ArgSettings::MultipleValues,
-                    ArgSettings::MultipleOccurrences,
-                    ArgSettings::Last,
-                ])
+                .setting(ArgSettings::MultipleValues)
+                .setting(ArgSettings::MultipleOccurrences)
+                .setting(ArgSettings::Last)
                 .value_name("ARGS"),
         );
     assert!(utils::compare_output(