// Std #[allow(deprecated, unused_imports)] use std::ascii::AsciiExt; use std::str::FromStr; bitflags! { struct Flags: u32 { const REQUIRED = 1; const MULTIPLE = 1 << 1; const EMPTY_VALS = 1 << 2; const GLOBAL = 1 << 3; const HIDDEN = 1 << 4; const TAKES_VAL = 1 << 5; const USE_DELIM = 1 << 6; const NEXT_LINE_HELP = 1 << 7; const R_UNLESS_ALL = 1 << 8; const REQ_DELIM = 1 << 9; const DELIM_NOT_SET = 1 << 10; const HIDE_POS_VALS = 1 << 11; const ALLOW_TAC_VALS = 1 << 12; const REQUIRE_EQUALS = 1 << 13; const LAST = 1 << 14; const HIDE_DEFAULT_VAL = 1 << 15; const CASE_INSENSITIVE = 1 << 16; const HIDE_ENV_VALS = 1 << 17; const HIDDEN_SHORT_H = 1 << 18; const HIDDEN_LONG_H = 1 << 19; } } #[doc(hidden)] #[derive(Debug, Clone, Copy)] pub struct ArgFlags(Flags); impl ArgFlags { pub fn new() -> Self { ArgFlags::default() } impl_settings!{ArgSettings, Required => Flags::REQUIRED, Multiple => Flags::MULTIPLE, EmptyValues => Flags::EMPTY_VALS, Global => Flags::GLOBAL, Hidden => Flags::HIDDEN, TakesValue => Flags::TAKES_VAL, UseValueDelimiter => Flags::USE_DELIM, NextLineHelp => Flags::NEXT_LINE_HELP, RequiredUnlessAll => Flags::R_UNLESS_ALL, RequireDelimiter => Flags::REQ_DELIM, ValueDelimiterNotSet => Flags::DELIM_NOT_SET, HidePossibleValues => Flags::HIDE_POS_VALS, AllowLeadingHyphen => Flags::ALLOW_TAC_VALS, RequireEquals => Flags::REQUIRE_EQUALS, Last => Flags::LAST, CaseInsensitive => Flags::CASE_INSENSITIVE, HideEnvValues => Flags::HIDE_ENV_VALS, HideDefaultValue => Flags::HIDE_DEFAULT_VAL, HiddenShortHelp => Flags::HIDDEN_SHORT_H, HiddenLongHelp => Flags::HIDDEN_LONG_H } } impl Default for ArgFlags { fn default() -> Self { ArgFlags(Flags::EMPTY_VALS | Flags::DELIM_NOT_SET) } } /// Various settings that apply to arguments and may be set, unset, and checked via getter/setter /// methods [`Arg::set`], [`Arg::unset`], and [`Arg::is_set`] /// /// [`Arg::set`]: ./struct.Arg.html#method.set /// [`Arg::unset`]: ./struct.Arg.html#method.unset /// [`Arg::is_set`]: ./struct.Arg.html#method.is_set #[derive(Debug, PartialEq, Copy, Clone)] pub enum ArgSettings { /// The argument must be used Required, /// The argument may be used multiple times such as `--flag --flag` Multiple, /// The argument allows empty values such as `--option ""` EmptyValues, /// The argument should be propagated down through all child [`SubCommand`]s /// /// [`SubCommand`]: ./struct.SubCommand.html Global, /// The argument should **not** be shown in help text Hidden, /// The argument accepts a value, such as `--option ` TakesValue, /// Determines if the argument allows values to be grouped via a delimiter UseValueDelimiter, /// Prints the help text on the line after the argument NextLineHelp, /// Requires the use of a value delimiter for all multiple values RequireDelimiter, /// Hides the possible values from the help string HidePossibleValues, /// Allows vals that start with a '-' AllowLeadingHyphen, /// Require options use `--option=val` syntax RequireEquals, /// Specifies that the arg is the last positional argument and may be accessed early via `--` /// syntax Last, /// Hides the default value from the help string HideDefaultValue, /// Makes `Arg::possible_values` case insensitive CaseInsensitive, /// Hides ENV values in the help message HideEnvValues, /// The argument should **not** be shown in short help text HiddenShortHelp, /// The argument should **not** be shown in long help text HiddenLongHelp, #[doc(hidden)] RequiredUnlessAll, #[doc(hidden)] ValueDelimiterNotSet, } impl FromStr for ArgSettings { type Err = String; fn from_str(s: &str) -> Result::Err> { match &*s.to_ascii_lowercase() { "required" => Ok(ArgSettings::Required), "multiple" => Ok(ArgSettings::Multiple), "global" => Ok(ArgSettings::Global), "emptyvalues" => Ok(ArgSettings::EmptyValues), "hidden" => Ok(ArgSettings::Hidden), "takesvalue" => Ok(ArgSettings::TakesValue), "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter), "nextlinehelp" => Ok(ArgSettings::NextLineHelp), "requiredunlessall" => Ok(ArgSettings::RequiredUnlessAll), "requiredelimiter" => Ok(ArgSettings::RequireDelimiter), "valuedelimiternotset" => Ok(ArgSettings::ValueDelimiterNotSet), "hidepossiblevalues" => Ok(ArgSettings::HidePossibleValues), "allowleadinghyphen" => Ok(ArgSettings::AllowLeadingHyphen), "requireequals" => Ok(ArgSettings::RequireEquals), "last" => Ok(ArgSettings::Last), "hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue), "caseinsensitive" => Ok(ArgSettings::CaseInsensitive), "hideenvvalues" => Ok(ArgSettings::HideEnvValues), "hiddenshorthelp" => Ok(ArgSettings::HiddenShortHelp), "hiddenlonghelp" => Ok(ArgSettings::HiddenLongHelp), _ => Err("unknown ArgSetting, cannot convert from str".to_owned()), } } } #[cfg(test)] mod test { use super::ArgSettings; #[test] fn arg_settings_fromstr() { assert_eq!( "allowleadinghyphen".parse::().unwrap(), ArgSettings::AllowLeadingHyphen ); assert_eq!( "emptyvalues".parse::().unwrap(), ArgSettings::EmptyValues ); assert_eq!( "global".parse::().unwrap(), ArgSettings::Global ); assert_eq!( "hidepossiblevalues".parse::().unwrap(), ArgSettings::HidePossibleValues ); assert_eq!( "hidden".parse::().unwrap(), ArgSettings::Hidden ); assert_eq!( "multiple".parse::().unwrap(), ArgSettings::Multiple ); assert_eq!( "nextlinehelp".parse::().unwrap(), ArgSettings::NextLineHelp ); assert_eq!( "requiredunlessall".parse::().unwrap(), ArgSettings::RequiredUnlessAll ); assert_eq!( "requiredelimiter".parse::().unwrap(), ArgSettings::RequireDelimiter ); assert_eq!( "required".parse::().unwrap(), ArgSettings::Required ); assert_eq!( "takesvalue".parse::().unwrap(), ArgSettings::TakesValue ); assert_eq!( "usevaluedelimiter".parse::().unwrap(), ArgSettings::UseValueDelimiter ); assert_eq!( "valuedelimiternotset".parse::().unwrap(), ArgSettings::ValueDelimiterNotSet ); assert_eq!( "requireequals".parse::().unwrap(), ArgSettings::RequireEquals ); assert_eq!("last".parse::().unwrap(), ArgSettings::Last); assert_eq!( "hidedefaultvalue".parse::().unwrap(), ArgSettings::HideDefaultValue ); assert_eq!( "caseinsensitive".parse::().unwrap(), ArgSettings::CaseInsensitive ); assert_eq!( "hideenvvalues".parse::().unwrap(), ArgSettings::HideEnvValues ); assert_eq!( "hiddenshorthelp".parse::().unwrap(), ArgSettings::HiddenShortHelp ); assert_eq!( "hiddenlonghelp".parse::().unwrap(), ArgSettings::HiddenLongHelp ); assert!("hahahaha".parse::().is_err()); } }