fix!: Remove yaml support

This commit is contained in:
Ed Page 2022-07-21 12:46:47 -05:00
parent 765af4198c
commit 99d92c916c
13 changed files with 15 additions and 905 deletions

16
Cargo.lock generated
View file

@ -140,7 +140,6 @@ dependencies = [
"trybuild",
"trycmd",
"unicase",
"yaml-rust",
]
[[package]]
@ -484,12 +483,6 @@ version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "log"
version = "0.4.17"
@ -1112,15 +1105,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "yansi"
version = "0.5.1"

View file

@ -60,7 +60,7 @@ default = [
"suggestions",
]
debug = ["clap_derive/debug", "backtrace"] # Enables debug messages
unstable-doc = ["derive", "cargo", "wrap_help", "yaml", "env", "unicode", "unstable-replace", "unstable-grouped"] # for docs.rs
unstable-doc = ["derive", "cargo", "wrap_help", "env", "unicode", "unstable-replace", "unstable-grouped"] # for docs.rs
# Used in default
std = ["indexmap/std"] # support for no_std in a backwards-compatible way
@ -73,7 +73,6 @@ deprecated = ["clap_derive/deprecated"] # Guided experience to prepare for next
derive = ["clap_derive", "once_cell"]
cargo = ["once_cell"] # Disable if you're not using Cargo, enables Cargo-env-var-dependent macros
wrap_help = ["terminal_size", "textwrap/terminal_size"]
yaml = ["yaml-rust"]
env = [] # Use environment variables during arg parsing
unicode = ["textwrap/unicode-width", "unicase"] # Support for unicode characters in arguments and help messages
@ -94,7 +93,6 @@ textwrap = { version = "0.15.0", default-features = false, features = [] }
unicase = { version = "2.6", optional = true }
indexmap = "1.0"
strsim = { version = "0.10", optional = true }
yaml-rust = { version = "0.4.1", optional = true }
atty = { version = "0.2", optional = true }
termcolor = { version = "1.1.1", optional = true }
terminal_size = { version = "0.1.12", optional = true }

View file

@ -15,8 +15,8 @@ MSRV?=1.56.1
_FEATURES = minimal default wasm full debug release
_FEATURES_minimal = --no-default-features --features "std"
_FEATURES_default =
_FEATURES_wasm = --features "deprecated derive cargo env unicode yaml unstable-replace unstable-grouped"
_FEATURES_full = --features "deprecated derive cargo env unicode yaml unstable-replace unstable-grouped wrap_help"
_FEATURES_wasm = --features "deprecated derive cargo env unicode unstable-replace unstable-grouped"
_FEATURES_full = --features "deprecated derive cargo env unicode unstable-replace unstable-grouped wrap_help"
_FEATURES_next = ${_FEATURES_full} --features unstable-v4
_FEATURES_debug = ${_FEATURES_full} --features debug
_FEATURES_release = ${_FEATURES_full} --release

View file

@ -2,8 +2,6 @@
// Std
use std::ops::BitOr;
#[cfg(feature = "yaml")]
use std::str::FromStr;
#[allow(unused)]
use crate::Arg;
@ -669,196 +667,3 @@ impl_settings! { AppSettings, AppFlags,
InferLongArgs
=> Flags::INFER_LONG_ARGS
}
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
impl FromStr for AppSettings {
type Err = String;
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match &*s.to_ascii_lowercase() {
"argrequiredelsehelp" => Ok(AppSettings::ArgRequiredElseHelp),
"subcommandprecedenceoverarg" => Ok(AppSettings::SubcommandPrecedenceOverArg),
"argsnegatesubcommands" => Ok(AppSettings::ArgsNegateSubcommands),
"allowexternalsubcommands" => Ok(AppSettings::AllowExternalSubcommands),
"strictutf8" => Ok(AppSettings::StrictUtf8),
"allowinvalidutf8forexternalsubcommands" => {
Ok(AppSettings::AllowInvalidUtf8ForExternalSubcommands)
}
"allowhyphenvalues" => Ok(AppSettings::AllowHyphenValues),
"allowleadinghyphen" => Ok(AppSettings::AllowLeadingHyphen),
"allownegativenumbers" => Ok(AppSettings::AllowNegativeNumbers),
"allowmissingpositional" => Ok(AppSettings::AllowMissingPositional),
"unifiedhelpmessage" => Ok(AppSettings::UnifiedHelpMessage),
"coloredhelp" => Ok(AppSettings::ColoredHelp),
"coloralways" => Ok(AppSettings::ColorAlways),
"colorauto" => Ok(AppSettings::ColorAuto),
"colornever" => Ok(AppSettings::ColorNever),
"dontdelimittrailingvalues" => Ok(AppSettings::DontDelimitTrailingValues),
"dontcollapseargsinusage" => Ok(AppSettings::DontCollapseArgsInUsage),
"derivedisplayorder" => Ok(AppSettings::DeriveDisplayOrder),
"disablecoloredhelp" => Ok(AppSettings::DisableColoredHelp),
"disablehelpsubcommand" => Ok(AppSettings::DisableHelpSubcommand),
"disablehelpflag" => Ok(AppSettings::DisableHelpFlag),
"disablehelpflags" => Ok(AppSettings::DisableHelpFlags),
"disableversionflag" => Ok(AppSettings::DisableVersionFlag),
"disableversion" => Ok(AppSettings::DisableVersion),
"propagateversion" => Ok(AppSettings::PropagateVersion),
"propagateversion" => Ok(AppSettings::GlobalVersion),
"hidepossiblevalues" => Ok(AppSettings::HidePossibleValues),
"hidepossiblevaluesinhelp" => Ok(AppSettings::HidePossibleValuesInHelp),
"helpexpected" => Ok(AppSettings::HelpExpected),
"hidden" => Ok(AppSettings::Hidden),
"noautohelp" => Ok(AppSettings::NoAutoHelp),
"noautoversion" => Ok(AppSettings::NoAutoVersion),
"nobinaryname" => Ok(AppSettings::NoBinaryName),
"subcommandsnegatereqs" => Ok(AppSettings::SubcommandsNegateReqs),
"subcommandrequired" => Ok(AppSettings::SubcommandRequired),
"subcommandrequiredelsehelp" => Ok(AppSettings::SubcommandRequiredElseHelp),
"uselongformatforhelpsubcommand" => Ok(AppSettings::UseLongFormatForHelpSubcommand),
"trailingvararg" => Ok(AppSettings::TrailingVarArg),
"unifiedhelp" => Ok(AppSettings::UnifiedHelp),
"nextlinehelp" => Ok(AppSettings::NextLineHelp),
"ignoreerrors" => Ok(AppSettings::IgnoreErrors),
"waitonerror" => Ok(AppSettings::WaitOnError),
"built" => Ok(AppSettings::Built),
"binnamebuilt" => Ok(AppSettings::BinNameBuilt),
"infersubcommands" => Ok(AppSettings::InferSubcommands),
"allargsoverrideself" => Ok(AppSettings::AllArgsOverrideSelf),
"inferlongargs" => Ok(AppSettings::InferLongArgs),
_ => Err(format!("unknown AppSetting: `{}`", s)),
}
}
}
#[cfg(test)]
mod test {
#[allow(clippy::cognitive_complexity)]
#[test]
#[cfg(feature = "yaml")]
fn app_settings_fromstr() {
use super::AppSettings;
assert_eq!(
"disablehelpflag".parse::<AppSettings>().unwrap(),
AppSettings::DisableHelpFlag
);
assert_eq!(
"argsnegatesubcommands".parse::<AppSettings>().unwrap(),
AppSettings::ArgsNegateSubcommands
);
assert_eq!(
"argrequiredelsehelp".parse::<AppSettings>().unwrap(),
AppSettings::ArgRequiredElseHelp
);
assert_eq!(
"subcommandprecedenceoverarg"
.parse::<AppSettings>()
.unwrap(),
AppSettings::SubcommandPrecedenceOverArg
);
assert_eq!(
"allowexternalsubcommands".parse::<AppSettings>().unwrap(),
AppSettings::AllowExternalSubcommands
);
assert_eq!(
"allowinvalidutf8forexternalsubcommands"
.parse::<AppSettings>()
.unwrap(),
AppSettings::AllowInvalidUtf8ForExternalSubcommands
);
assert_eq!(
"allowhyphenvalues".parse::<AppSettings>().unwrap(),
AppSettings::AllowHyphenValues
);
assert_eq!(
"allownegativenumbers".parse::<AppSettings>().unwrap(),
AppSettings::AllowNegativeNumbers
);
assert_eq!(
"disablehelpsubcommand".parse::<AppSettings>().unwrap(),
AppSettings::DisableHelpSubcommand
);
assert_eq!(
"disableversionflag".parse::<AppSettings>().unwrap(),
AppSettings::DisableVersionFlag
);
assert_eq!(
"dontcollapseargsinusage".parse::<AppSettings>().unwrap(),
AppSettings::DontCollapseArgsInUsage
);
assert_eq!(
"dontdelimittrailingvalues".parse::<AppSettings>().unwrap(),
AppSettings::DontDelimitTrailingValues
);
assert_eq!(
"derivedisplayorder".parse::<AppSettings>().unwrap(),
AppSettings::DeriveDisplayOrder
);
assert_eq!(
"disablecoloredhelp".parse::<AppSettings>().unwrap(),
AppSettings::DisableColoredHelp
);
assert_eq!(
"propagateversion".parse::<AppSettings>().unwrap(),
AppSettings::PropagateVersion
);
assert_eq!(
"hidden".parse::<AppSettings>().unwrap(),
AppSettings::Hidden
);
assert_eq!(
"hidepossiblevalues".parse::<AppSettings>().unwrap(),
AppSettings::HidePossibleValues
);
assert_eq!(
"helpexpected".parse::<AppSettings>().unwrap(),
AppSettings::HelpExpected
);
assert_eq!(
"nobinaryname".parse::<AppSettings>().unwrap(),
AppSettings::NoBinaryName
);
assert_eq!(
"nextlinehelp".parse::<AppSettings>().unwrap(),
AppSettings::NextLineHelp
);
assert_eq!(
"subcommandsnegatereqs".parse::<AppSettings>().unwrap(),
AppSettings::SubcommandsNegateReqs
);
assert_eq!(
"subcommandrequired".parse::<AppSettings>().unwrap(),
AppSettings::SubcommandRequired
);
assert_eq!(
"subcommandrequiredelsehelp".parse::<AppSettings>().unwrap(),
AppSettings::SubcommandRequiredElseHelp
);
assert_eq!(
"uselongformatforhelpsubcommand"
.parse::<AppSettings>()
.unwrap(),
AppSettings::UseLongFormatForHelpSubcommand
);
assert_eq!(
"trailingvararg".parse::<AppSettings>().unwrap(),
AppSettings::TrailingVarArg
);
assert_eq!(
"waitonerror".parse::<AppSettings>().unwrap(),
AppSettings::WaitOnError
);
assert_eq!("built".parse::<AppSettings>().unwrap(), AppSettings::Built);
assert_eq!(
"binnamebuilt".parse::<AppSettings>().unwrap(),
AppSettings::BinNameBuilt
);
assert_eq!(
"infersubcommands".parse::<AppSettings>().unwrap(),
AppSettings::InferSubcommands
);
assert!("hahahaha".parse::<AppSettings>().is_err());
}
}

View file

@ -13,9 +13,6 @@ use std::{
#[cfg(feature = "env")]
use std::{env, ffi::OsString};
#[cfg(feature = "yaml")]
use yaml_rust::Yaml;
// Internal
use crate::builder::usage_parser::UsageParser;
use crate::builder::ArgPredicate;
@ -4655,83 +4652,6 @@ impl<'help> Arg<'help> {
Self::new(n)
}
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
)
)]
#[doc(hidden)]
pub fn from_yaml(y: &'help Yaml) -> Self {
#![allow(deprecated)]
let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
// We WANT this to panic on error...so expect() is good.
let (name_yaml, yaml) = yaml_file_hash
.iter()
.next()
.expect("There must be one arg in the YAML file");
let name_str = name_yaml.as_str().expect("Arg name must be a string");
let mut a = Arg::new(name_str);
for (k, v) in yaml.as_hash().expect("Arg must be a hash") {
a = match k.as_str().expect("Arg fields must be strings") {
"short" => yaml_to_char!(a, v, short),
"long" => yaml_to_str!(a, v, long),
"aliases" => yaml_vec_or_str!(a, v, alias),
"help" => yaml_to_str!(a, v, help),
"long_help" => yaml_to_str!(a, v, long_help),
"required" => yaml_to_bool!(a, v, required),
"required_if" => yaml_tuple2!(a, v, required_if_eq),
"required_ifs" => yaml_tuple2!(a, v, required_if_eq),
"takes_value" => yaml_to_bool!(a, v, takes_value),
"index" => yaml_to_usize!(a, v, index),
"global" => yaml_to_bool!(a, v, global),
"multiple" => yaml_to_bool!(a, v, multiple),
"hidden" => yaml_to_bool!(a, v, hide),
"next_line_help" => yaml_to_bool!(a, v, next_line_help),
"group" => yaml_to_str!(a, v, group),
"number_of_values" => yaml_to_usize!(a, v, number_of_values),
"max_values" => yaml_to_usize!(a, v, max_values),
"min_values" => yaml_to_usize!(a, v, min_values),
"value_name" => yaml_to_str!(a, v, value_name),
"use_delimiter" => yaml_to_bool!(a, v, use_delimiter),
"allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values),
"last" => yaml_to_bool!(a, v, last),
"require_delimiter" => yaml_to_bool!(a, v, require_delimiter),
"value_delimiter" => yaml_to_char!(a, v, value_delimiter),
"required_unless" => yaml_to_str!(a, v, required_unless_present),
"display_order" => yaml_to_usize!(a, v, display_order),
"default_value" => yaml_to_str!(a, v, default_value),
"default_value_if" => yaml_tuple3!(a, v, default_value_if),
"default_value_ifs" => yaml_tuple3!(a, v, default_value_if),
#[cfg(feature = "env")]
"env" => yaml_to_str!(a, v, env),
"value_names" => yaml_vec_or_str!(a, v, value_name),
"groups" => yaml_vec_or_str!(a, v, group),
"requires" => yaml_vec_or_str!(a, v, requires),
"requires_if" => yaml_tuple2!(a, v, requires_if),
"requires_ifs" => yaml_tuple2!(a, v, requires_if),
"conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
"overrides_with" => yaml_to_str!(a, v, overrides_with),
"possible_values" => yaml_vec_or_str!(a, v, possible_value),
"case_insensitive" => yaml_to_bool!(a, v, ignore_case),
"required_unless_one" => yaml_vec!(a, v, required_unless_present_any),
"required_unless_all" => yaml_vec!(a, v, required_unless_present_all),
s => {
panic!(
"Unknown setting '{}' in YAML file for arg '{}'",
s, name_str
)
}
}
}
a
}
/// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!].
#[cfg_attr(
feature = "deprecated",

View file

@ -1,9 +1,6 @@
// Internal
use crate::util::{Id, Key};
#[cfg(feature = "yaml")]
use yaml_rust::Yaml;
/// Family of related [arguments].
///
/// By placing arguments in a logical group, you can create easier requirement and
@ -444,20 +441,6 @@ impl<'help> ArgGroup<'help> {
pub fn with_name<S: Into<&'help str>>(n: S) -> Self {
Self::new(n)
}
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
note = "Maybe clap::Parser would fit your use case? (Issue #3087)"
)
)]
#[doc(hidden)]
pub fn from_yaml(yaml: &'help Yaml) -> Self {
Self::from(yaml)
}
}
impl<'help> From<&'_ ArgGroup<'help>> for ArgGroup<'help> {
@ -474,65 +457,23 @@ impl<'help> From<&'_ ArgGroup<'help>> for ArgGroup<'help> {
}
}
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
impl<'help> From<&'help Yaml> for ArgGroup<'help> {
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
fn from(y: &'help Yaml) -> Self {
let b = y.as_hash().expect("ArgGroup::from::<Yaml> expects a table");
// We WANT this to panic on error...so expect() is good.
let mut a = ArgGroup::default();
let group_settings = if b.len() == 1 {
let name_yaml = b.keys().next().expect("failed to get name");
let name_str = name_yaml
.as_str()
.expect("failed to convert arg YAML name to str");
a.name = name_str;
a.id = Id::from(&a.name);
b.get(name_yaml)
.expect("failed to get name_str")
.as_hash()
.expect("failed to convert to a hash")
} else {
b
};
for (k, v) in group_settings {
a = match k.as_str().unwrap() {
"required" => a.required(v.as_bool().unwrap()),
"multiple" => a.multiple(v.as_bool().unwrap()),
"args" => yaml_vec_or_str!(a, v, arg),
"arg" => {
if let Some(ys) = v.as_str() {
a = a.arg(ys);
}
a
}
"requires" => yaml_vec_or_str!(a, v, requires),
"conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
"name" => {
if let Some(ys) = v.as_str() {
a = a.id(ys);
}
a
}
s => panic!(
"Unknown ArgGroup setting '{}' in YAML file for \
ArgGroup '{}'",
s, a.name
),
}
impl Clone for ArgGroup<'_> {
fn clone(&self) -> Self {
ArgGroup {
id: self.id.clone(),
name: self.name,
required: self.required,
args: self.args.clone(),
requires: self.requires.clone(),
conflicts: self.conflicts.clone(),
multiple: self.multiple,
}
a
}
}
#[cfg(test)]
mod test {
use super::ArgGroup;
#[cfg(feature = "yaml")]
use yaml_rust::YamlLoader;
#[test]
fn groups() {
@ -581,35 +522,6 @@ mod test {
assert_eq!(g2.conflicts, confs);
}
#[cfg(feature = "yaml")]
#[test]
fn test_yaml() {
let g_yaml = "name: test
args:
- a1
- a4
- a2
- a3
conflicts_with:
- c1
- c2
- c3
- c4
requires:
- r1
- r2
- r3
- r4";
let yaml = &YamlLoader::load_from_str(g_yaml).expect("failed to load YAML file")[0];
let g = ArgGroup::from(yaml);
let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()];
let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()];
let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()];
assert_eq!(g.args, args);
assert_eq!(g.requires, reqs);
assert_eq!(g.conflicts, confs);
}
// This test will *fail to compile* if ArgGroup is not Send + Sync
#[test]
fn arg_group_send_sync() {
@ -617,17 +529,3 @@ requires:
foo(ArgGroup::new("test"))
}
}
impl Clone for ArgGroup<'_> {
fn clone(&self) -> Self {
ArgGroup {
id: self.id.clone(),
name: self.name,
required: self.required,
args: self.args.clone(),
requires: self.requires.clone(),
conflicts: self.conflicts.clone(),
multiple: self.multiple,
}
}
}

View file

@ -2,8 +2,6 @@
// Std
use std::ops::BitOr;
#[cfg(feature = "yaml")]
use std::str::FromStr;
// Third party
use bitflags::bitflags;
@ -328,129 +326,3 @@ impl_settings! { ArgSettings, ArgFlags,
AllowInvalidUtf8 => Flags::UTF8_NONE,
Exclusive => Flags::EXCLUSIVE
}
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
impl FromStr for ArgSettings {
type Err = String;
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match &*s.to_ascii_lowercase() {
"required" => Ok(ArgSettings::Required),
"multipleoccurrences" => Ok(ArgSettings::MultipleOccurrences),
"multiplevalues" => Ok(ArgSettings::MultipleValues),
"multiple" => Ok(ArgSettings::Multiple),
"forbidemptyvalues" => Ok(ArgSettings::ForbidEmptyValues),
"global" => Ok(ArgSettings::Global),
"hidden" => Ok(ArgSettings::Hidden),
"takesvalue" => Ok(ArgSettings::TakesValue),
"usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter),
"nextlinehelp" => Ok(ArgSettings::NextLineHelp),
"requiredelimiter" => Ok(ArgSettings::RequireDelimiter),
"hidepossiblevalues" => Ok(ArgSettings::HidePossibleValues),
"allowhyphenvalues" => Ok(ArgSettings::AllowHyphenValues),
"allowleadinghypyhen" => Ok(ArgSettings::AllowLeadingHyphen),
"requireequals" => Ok(ArgSettings::RequireEquals),
"last" => Ok(ArgSettings::Last),
"ignorecase" => Ok(ArgSettings::IgnoreCase),
"caseinsensitive" => Ok(ArgSettings::CaseInsensitive),
#[cfg(feature = "env")]
"hideenv" => Ok(ArgSettings::HideEnv),
#[cfg(feature = "env")]
"hideenvvalues" => Ok(ArgSettings::HideEnvValues),
"hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue),
"hiddenshorthelp" => Ok(ArgSettings::HiddenShortHelp),
"hiddenlonghelp" => Ok(ArgSettings::HiddenLongHelp),
"allowinvalidutf8" => Ok(ArgSettings::AllowInvalidUtf8),
"exclusive" => Ok(ArgSettings::Exclusive),
_ => Err(format!("unknown AppSetting: `{}`", s)),
}
}
}
#[cfg(test)]
mod test {
#[test]
#[cfg(feature = "yaml")]
fn arg_settings_fromstr() {
use super::ArgSettings;
assert_eq!(
"allowhyphenvalues".parse::<ArgSettings>().unwrap(),
ArgSettings::AllowHyphenValues
);
assert_eq!(
"forbidemptyvalues".parse::<ArgSettings>().unwrap(),
ArgSettings::ForbidEmptyValues
);
assert_eq!(
"hidepossiblevalues".parse::<ArgSettings>().unwrap(),
ArgSettings::HidePossibleValues
);
assert_eq!(
"hidden".parse::<ArgSettings>().unwrap(),
ArgSettings::Hidden
);
assert_eq!(
"nextlinehelp".parse::<ArgSettings>().unwrap(),
ArgSettings::NextLineHelp
);
assert_eq!(
"requiredelimiter".parse::<ArgSettings>().unwrap(),
ArgSettings::RequireDelimiter
);
assert_eq!(
"required".parse::<ArgSettings>().unwrap(),
ArgSettings::Required
);
assert_eq!(
"takesvalue".parse::<ArgSettings>().unwrap(),
ArgSettings::TakesValue
);
assert_eq!(
"usevaluedelimiter".parse::<ArgSettings>().unwrap(),
ArgSettings::UseValueDelimiter
);
assert_eq!(
"requireequals".parse::<ArgSettings>().unwrap(),
ArgSettings::RequireEquals
);
assert_eq!("last".parse::<ArgSettings>().unwrap(), ArgSettings::Last);
assert_eq!(
"hidedefaultvalue".parse::<ArgSettings>().unwrap(),
ArgSettings::HideDefaultValue
);
assert_eq!(
"ignorecase".parse::<ArgSettings>().unwrap(),
ArgSettings::IgnoreCase
);
#[cfg(feature = "env")]
assert_eq!(
"hideenv".parse::<ArgSettings>().unwrap(),
ArgSettings::HideEnv
);
#[cfg(feature = "env")]
assert_eq!(
"hideenvvalues".parse::<ArgSettings>().unwrap(),
ArgSettings::HideEnvValues
);
assert_eq!(
"hiddenshorthelp".parse::<ArgSettings>().unwrap(),
ArgSettings::HiddenShortHelp
);
assert_eq!(
"hiddenlonghelp".parse::<ArgSettings>().unwrap(),
ArgSettings::HiddenLongHelp
);
assert_eq!(
"allowinvalidutf8".parse::<ArgSettings>().unwrap(),
ArgSettings::AllowInvalidUtf8
);
assert_eq!(
"exclusive".parse::<ArgSettings>().unwrap(),
ArgSettings::Exclusive
);
assert!("hahahaha".parse::<ArgSettings>().is_err());
}
}

View file

@ -9,10 +9,6 @@ use std::io;
use std::ops::Index;
use std::path::Path;
// Third Party
#[cfg(feature = "yaml")]
use yaml_rust::Yaml;
// Internal
use crate::builder::app_settings::{AppFlags, AppSettings};
use crate::builder::arg_settings::ArgSettings;
@ -1383,10 +1379,8 @@ impl<'help> App<'help> {
/// # Examples
///
/// ```ignore
/// # use clap::{Command, load_yaml};
/// let yaml = load_yaml!("cmd.yaml");
/// let cmd = Command::from(yaml)
/// .name(crate_name!());
/// let cmd = clap::command!()
/// .name("foo");
///
/// // continued logic goes here, such as `cmd.get_matches()` etc.
/// ```
@ -3785,101 +3779,6 @@ impl<'help> App<'help> {
/// Deprecated
impl<'help> App<'help> {
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
)
)]
#[doc(hidden)]
pub fn from_yaml(y: &'help Yaml) -> Self {
#![allow(deprecated)]
let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
// We WANT this to panic on error...so expect() is good.
let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() {
(App::new(name), yaml_file_hash, "cmd".into())
} else {
let (name_yaml, value_yaml) = yaml_file_hash
.iter()
.next()
.expect("There must be one subcommand in the YAML file");
let name_str = name_yaml
.as_str()
.expect("Subcommand name must be a string");
(
App::new(name_str),
value_yaml.as_hash().expect("Subcommand must be a hash"),
format!("subcommand '{}'", name_str),
)
};
for (k, v) in yaml {
a = match k.as_str().expect("App fields must be strings") {
"version" => yaml_to_str!(a, v, version),
"long_version" => yaml_to_str!(a, v, long_version),
"author" => yaml_to_str!(a, v, author),
"bin_name" => yaml_to_str!(a, v, bin_name),
"about" => yaml_to_str!(a, v, about),
"long_about" => yaml_to_str!(a, v, long_about),
"before_help" => yaml_to_str!(a, v, before_help),
"after_help" => yaml_to_str!(a, v, after_help),
"template" => yaml_to_str!(a, v, help_template),
"usage" => yaml_to_str!(a, v, override_usage),
"help" => yaml_to_str!(a, v, override_help),
"help_message" => yaml_to_str!(a, v, help_message),
"version_message" => yaml_to_str!(a, v, version_message),
"alias" => yaml_to_str!(a, v, alias),
"aliases" => yaml_vec_or_str!(a, v, alias),
"visible_alias" => yaml_to_str!(a, v, visible_alias),
"visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
"display_order" => yaml_to_usize!(a, v, display_order),
"args" => {
if let Some(vec) = v.as_vec() {
for arg_yaml in vec {
a = a.arg(Arg::from_yaml(arg_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"subcommands" => {
if let Some(vec) = v.as_vec() {
for sc_yaml in vec {
a = a.subcommand(App::from_yaml(sc_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"groups" => {
if let Some(vec) = v.as_vec() {
for ag_yaml in vec {
a = a.group(ArgGroup::from(ag_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"setting" | "settings" => {
yaml_to_setting!(a, v, setting, AppSettings, "AppSetting", err)
}
"global_setting" | "global_settings" => {
yaml_to_setting!(a, v, global_setting, AppSettings, "AppSetting", err)
}
_ => a,
}
}
a
}
/// Deprecated, replaced with [`Command::override_usage`]
#[cfg_attr(
feature = "deprecated",

View file

@ -1,180 +0,0 @@
#[cfg(feature = "yaml")]
macro_rules! yaml_tuple2 {
($a:ident, $v:ident, $c:ident) => {{
if let Some(vec) = $v.as_vec() {
for ys in vec {
if let Some(tup) = ys.as_vec() {
debug_assert_eq!(2, tup.len());
$a = $a.$c(yaml_str!(tup[0]), yaml_str!(tup[1]));
} else {
panic!("Failed to convert YAML value to vec");
}
}
} else {
panic!("Failed to convert YAML value to vec");
}
$a
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_tuple3 {
($a:ident, $v:ident, $c:ident) => {{
if let Some(vec) = $v.as_vec() {
for ys in vec {
if let Some(tup) = ys.as_vec() {
debug_assert_eq!(3, tup.len());
$a = $a.$c(
yaml_str!(tup[0]),
yaml_opt_str!(tup[1]),
yaml_opt_str!(tup[2]),
);
} else {
panic!("Failed to convert YAML value to vec");
}
}
} else {
panic!("Failed to convert YAML value to vec");
}
$a
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_vec_or_str {
($a:ident, $v:ident, $c:ident) => {{
let maybe_vec = $v.as_vec();
if let Some(vec) = maybe_vec {
for ys in vec {
if let Some(s) = ys.as_str() {
$a = $a.$c(s);
} else {
panic!("Failed to convert YAML value {:?} to a string", ys);
}
}
} else {
if let Some(s) = $v.as_str() {
$a = $a.$c(s);
} else {
panic!(
"Failed to convert YAML value {:?} to either a vec or string",
$v
);
}
}
$a
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_vec {
($a:ident, $v:ident, $c:ident) => {{
let maybe_vec = $v.as_vec();
if let Some(vec) = maybe_vec {
let content = vec.into_iter().map(|ys| {
if let Some(s) = ys.as_str() {
s
} else {
panic!("Failed to convert YAML value {:?} to a string", ys);
}
});
$a = $a.$c(content)
} else {
panic!("Failed to convert YAML value {:?} to a vec", $v);
}
$a
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_opt_str {
($v:expr) => {{
if !$v.is_null() {
Some(
$v.as_str()
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)),
)
} else {
None
}
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_char {
($v:expr) => {{
$v.as_str()
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))
.chars()
.next()
.unwrap_or_else(|| panic!("Expected char"))
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_str {
($v:expr) => {{
$v.as_str()
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_to_char {
($a:ident, $v:ident, $c:ident) => {{
$a.$c(yaml_char!($v))
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_to_str {
($a:ident, $v:ident, $c:ident) => {{
$a.$c(yaml_str!($v))
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_to_bool {
($a:ident, $v:ident, $c:ident) => {{
$a.$c($v
.as_bool()
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)))
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_to_usize {
($a:ident, $v:ident, $c:ident) => {{
$a.$c($v
.as_i64()
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))
as usize)
}};
}
#[cfg(feature = "yaml")]
macro_rules! yaml_to_setting {
($a:ident, $v:ident, $c:ident, $s:ident, $t:literal, $n:expr) => {{
if let Some(v) = $v.as_vec() {
for ys in v {
if let Some(s) = ys.as_str() {
$a = $a.$c(s.parse::<$s>().unwrap_or_else(|_| {
panic!("Unknown {} '{}' found in YAML file for {}", $t, s, $n)
}));
} else {
panic!(
"Failed to convert YAML {:?} value to an array of strings",
$v
);
}
}
} else if let Some(v) = $v.as_str() {
$a = $a.$c(v
.parse::<$s>()
.unwrap_or_else(|_| panic!("Unknown {} '{}' found in YAML file for {}", $t, v, $n)))
} else {
panic!("Failed to convert YAML {:?} value to a string", $v);
}
$a
}};
}

View file

@ -1,8 +1,5 @@
//! Define [`Command`] line [arguments][`Arg`]
#[macro_use]
mod macros;
mod action;
mod app_settings;
mod arg;

View file

@ -115,18 +115,6 @@ pub use crate::error::{ErrorKind, Result};
#[allow(deprecated)]
pub use crate::parser::{Indices, OsValues, ValueSource, Values};
#[cfg(feature = "yaml")]
#[doc(hidden)]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
)
)]
#[doc(hidden)]
pub use yaml_rust::YamlLoader;
#[cfg(feature = "derive")]
#[doc(hidden)]
pub use clap_derive::{self, *};
@ -211,19 +199,4 @@ impl SubCommand {
pub fn with_name<'help>(name: &str) -> App<'help> {
Command::new(name)
}
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
)
)]
#[doc(hidden)]
pub fn from_yaml(yaml: &yaml_rust::Yaml) -> App {
#![allow(deprecated)]
Command::from_yaml(yaml)
}
}

View file

@ -1,21 +1,3 @@
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
)
)]
#[doc(hidden)]
#[macro_export]
macro_rules! load_yaml {
($yaml:expr) => {
&$crate::YamlLoader::load_from_str(include_str!($yaml)).expect("failed to load YAML file")
[0]
};
}
/// Deprecated, replaced with [`ArgMatches::value_of_t`][crate::ArgMatches::value_of_t]
#[macro_export]
#[cfg_attr(

View file

@ -1,38 +0,0 @@
#![cfg(feature = "yaml")]
#![allow(deprecated)]
use clap::{load_yaml, Command};
#[test]
fn create_cmd_from_yaml() {
let yml = load_yaml!("app.yml");
Command::from_yaml(yml);
}
#[test]
fn help_message() {
let yml = load_yaml!("app.yml");
let mut cmd = Command::from_yaml(yml);
// Generate the full help message!
let _ = cmd.get_matches_from_safe_borrow(Vec::<String>::new());
let mut help_buffer = Vec::new();
cmd.write_help(&mut help_buffer).unwrap();
let help_string = String::from_utf8(help_buffer).unwrap();
println!("{}", &help_string);
assert!(help_string.contains("tests positionals with exclusions\n"));
}
#[test]
fn author() {
let yml = load_yaml!("app.yml");
let mut cmd = Command::from_yaml(yml);
// Generate the full help message!
let _ = cmd.get_matches_from_safe_borrow(Vec::<String>::new());
let mut help_buffer = Vec::new();
cmd.write_help(&mut help_buffer).unwrap();
let help_string = String::from_utf8(help_buffer).unwrap();
println!("{}", &help_string);
assert!(help_string.contains("Kevin K. <kbknapp@gmail.com>"));
}